17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_network_transaction.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <math.h>  // ceil
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdarg.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_writer.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/memory/weak_ptr.h"
1923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/run_loop.h"
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_file_util.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/auth.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/capturing_net_log.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/load_timing_info.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/load_timing_info_test_util.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log_unittest.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/request_priority.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_completion_callback.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_data_directory.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_bytes_element_reader.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_data_stream.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/upload_file_element_reader.h"
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/mock_cert_verifier.h"
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/dns/host_cache.h"
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/dns/mock_host_resolver.h"
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/http/http_auth_challenge_tokenizer.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_auth_handler_digest.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_auth_handler_mock.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_auth_handler_ntlm.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_basic_stream.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_network_session.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_network_session_peer.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_server_properties_impl.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_stream.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_stream_factory.h"
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/http/http_transaction_test_util.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_config_service_fixed.h"
513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "net/proxy/proxy_info.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_resolver.h"
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_service.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_factory.h"
55a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "net/socket/client_socket_pool_manager.h"
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/mock_client_socket_pool_manager.h"
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/socket/next_proto.h"
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/socket_test_util.h"
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/ssl_client_socket.h"
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_framer.h"
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_session.h"
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_session_pool.h"
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/spdy/spdy_test_util_common.h"
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_cert_request_info.h"
653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "net/ssl/ssl_config_service.h"
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_config_service_defaults.h"
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_info.h"
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/test/cert_test_util.h"
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/websockets/websocket_handshake_stream_base.h"
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/platform_test.h"
72ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "url/gurl.h"
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::ASCIIToUTF16;
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kBar(ASCIIToUTF16("bar"));
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kBar2(ASCIIToUTF16("bar2"));
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kBar3(ASCIIToUTF16("bar3"));
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kBaz(ASCIIToUTF16("baz"));
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kFirst(ASCIIToUTF16("first"));
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kFoo(ASCIIToUTF16("foo"));
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kFoo2(ASCIIToUTF16("foo2"));
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kFoo3(ASCIIToUTF16("foo3"));
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kFou(ASCIIToUTF16("fou"));
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kSecond(ASCIIToUTF16("second"));
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return session->GetTransportSocketPool(
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return session->GetSSLSocketPool(
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool IsTransportSocketPoolStalled(net::HttpNetworkSession* session) {
1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return session->GetTransportSocketPool(
1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IsStalled();
1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Takes in a Value created from a NetLogHttpResponseParameter, and returns
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a JSONified list of headers as a single string.  Uses single quotes instead
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of double quotes for easier comparison.  Returns false on failure.
1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!params)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::ListValue* header_list;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!params->GetList("headers", &header_list))
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string double_quote_headers;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::JSONWriter::Write(header_list, &double_quote_headers);
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::ReplaceChars(double_quote_headers, "\"", "'", headers);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// used.
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.socket_reused);
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.send_start.is_null());
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Set at a higher level.
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start_time.is_null());
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start.is_null());
14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// used.
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             int connect_timing_flags) {
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.socket_reused);
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                   connect_timing_flags);
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.connect_timing.connect_end,
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.send_start);
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Set at a higher level.
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start_time.is_null());
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start.is_null());
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// used.
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.socket_reused);
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_start,
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.proxy_resolve_end);
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_end,
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.send_start);
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Set at a higher level.
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start_time.is_null());
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start.is_null());
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// used.
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    int connect_timing_flags) {
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.socket_reused);
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_start,
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.proxy_resolve_end);
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_end,
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.connect_timing.connect_start);
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   connect_timing_flags);
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.connect_timing.connect_end,
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.send_start);
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Set at a higher level.
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start_time.is_null());
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start.is_null());
20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SpdySessionDependencies::SpdyCreateSession(session_deps);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class HttpNetworkTransactionTest
2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : public PlatformTest,
2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      public ::testing::WithParamInterface<NextProto> {
227a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) public:
2287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual ~HttpNetworkTransactionTest() {
229a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // Important to restore the per-pool limit first, since the pool limit must
230a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // always be greater than group limit, and the tests reduce both limits.
231a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    ClientSocketPoolManager::set_max_sockets_per_pool(
232a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
233a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    ClientSocketPoolManager::set_max_sockets_per_group(
234a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
235a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
236a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
2387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  HttpNetworkTransactionTest()
2397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      : spdy_util_(GetParam()),
2407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        session_deps_(GetParam()),
241a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
242a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            HttpNetworkSession::NORMAL_SOCKET_POOL)),
243a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
244a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            HttpNetworkSession::NORMAL_SOCKET_POOL)) {
245a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct SimpleGetHelperResult {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string status_line;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string response_data;
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int64 totalReceivedBytes;
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LoadTimingInfo load_timing_info;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Empty the current queue.
26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PlatformTest::TearDown();
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // This is the expected return from a current server advertising SPDY.
271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string GetAlternateProtocolHttpHeader() {
272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return
273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        std::string("Alternate-Protocol: 443:") +
274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        "\r\n\r\n";
276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Either |write_failure| specifies a write failure or |read_failure|
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // specifies a read failure when using a reused socket.  In either case, the
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // failure should cause the network transaction to resend the request, and the
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other argument should be NULL.
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const MockRead* read_failure);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Either |write_failure| specifies a write failure or |read_failure|
28623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // specifies a read failure when using a reused socket.  In either case, the
28723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // failure should cause the network transaction to resend the request, and the
28823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // other argument should be NULL.
28923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
290effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                        const MockRead* read_failure,
291effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                        bool use_spdy);
29223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               size_t data_count) {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleGetHelperResult out;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/");
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CapturingBoundNetLog log;
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.net_log = log.bound().net_log();
3048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
3068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < data_count; ++i) {
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.socket_factory->AddSocketDataProvider(data[i]);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_TRUE(log.bound().IsLogging());
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), log.bound());
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.rv = callback.WaitForResult();
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Even in the failure cases that use this function, connections are always
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // successfully established before the error.
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (out.rv != OK)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return out;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Can't use ASSERT_* inside helper functions like this, so
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // return an error.
331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (response == NULL || response->headers.get() == NULL) {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      out.rv = ERR_UNEXPECTED;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return out;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.status_line = response->headers->GetStatusLine();
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ("127.0.0.1", response->socket_address.host());
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(80, response->socket_address.port());
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ReadTransaction(trans.get(), &out.response_data);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::CapturingNetLog::CapturedEntryList entries;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    log.GetEntries(&entries);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t pos = ExpectLogContainsSomewhere(
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NetLog::PHASE_NONE);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExpectLogContainsSomewhere(
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entries, pos,
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NetLog::PHASE_NONE);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string line;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("GET / HTTP/1.1\r\n", line);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    HttpRequestHeaders request_headers;
358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::string value;
360eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_TRUE(request_headers.GetHeader("Host", &value));
361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_EQ("www.google.com", value);
362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_EQ("keep-alive", value);
364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::string response_headers;
366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              response_headers);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    out.totalReceivedBytes = trans->GetTotalReceivedBytes();
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return out;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        size_t reads_count) {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider* data[] = { &reads };
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SimpleGetHelperForData(data, 1);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int64 size = 0;
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (size_t i = 0; i < reads_count; ++i)
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      size += data_reads[i].data_len;
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return size;
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             int expected_status);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ConnectStatusHelper(const MockRead& status);
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void BypassHostCacheOnRefreshHelper(int load_flags);
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void CheckErrorIsPassedBack(int error, IoMode mode);
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
397a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SpdyTestUtil spdy_util_;
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SpdySessionDependencies session_deps_;
399a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
400a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Original socket limits.  Some tests set these.  Safest to always restore
401a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // them once each test has been run.
402a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  int old_max_group_sockets_;
403a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  int old_max_pool_sockets_;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(
4077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    NextProto,
4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    HttpNetworkTransactionTest,
4094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    testing::Values(kProtoDeprecatedSPDY2,
410a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                    kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class BeforeNetworkStartHandler {
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit BeforeNetworkStartHandler(bool defer)
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : defer_on_before_network_start_(defer),
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        observed_before_network_start_(false) {}
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void OnBeforeNetworkStart(bool* defer) {
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *defer = defer_on_before_network_start_;
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    observed_before_network_start_ = true;
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool observed_before_network_start() const {
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return observed_before_network_start_;
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const bool defer_on_before_network_start_;
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool observed_before_network_start_;
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fill |str| with a long header list that consumes >= |size| bytes.
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FillLargeHeadersString(std::string* str, int size) {
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* row =
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int sizeof_row = strlen(row);
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int num_rows = static_cast<int>(
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ceil(static_cast<float>(size) / sizeof_row));
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int sizeof_data = num_rows * sizeof_row;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(sizeof_data >= size);
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  str->reserve(sizeof_data);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < num_rows; ++i)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    str->append(row, sizeof_row);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Alternative functions that eliminate randomness and dependency on the local
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// host name so that the generated NTLM messages are reproducible.
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockGenerateRandom1(uint8* output, size_t n) {
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const uint8 bytes[] = {
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static size_t current_byte = 0;
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < n; ++i) {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    output[i] = bytes[current_byte++];
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_byte %= arraysize(bytes);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockGenerateRandom2(uint8* output, size_t n) {
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const uint8 bytes[] = {
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static size_t current_byte = 0;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < n; ++i) {
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    output[i] = bytes[current_byte++];
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_byte %= arraysize(bytes);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string MockGetHostName() {
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return "WTC-WIN7";
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename ParentPool>
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CaptureGroupNameSocketPool : public ParentPool {
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptureGroupNameSocketPool(HostResolver* host_resolver,
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             CertVerifier* cert_verifier);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string last_group_name_received() const {
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return last_group_name_;
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int RequestSocket(const std::string& group_name,
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const void* socket_params,
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            RequestPriority priority,
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            ClientSocketHandle* handle,
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const CompletionCallback& callback,
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const BoundNetLog& net_log) {
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_group_name_ = group_name;
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_IO_PENDING;
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CancelRequest(const std::string& group_name,
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ClientSocketHandle* handle) {}
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ReleaseSocket(const std::string& group_name,
5023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             scoped_ptr<StreamSocket> socket,
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int id) {}
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CloseIdleSockets() {}
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int IdleSocketCount() const {
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int IdleSocketCountInGroup(const std::string& group_name) const {
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual LoadState GetLoadState(const std::string& group_name,
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const ClientSocketHandle* handle) const {
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return LOAD_STATE_IDLE;
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual base::TimeDelta ConnectionTimeout() const {
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::TimeDelta();
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string last_group_name_;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameTransportSocketPool;
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameHttpProxySocketPool;
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameSOCKSSocketPool;
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameSSLSocketPool;
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename ParentPool>
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostResolver* host_resolver,
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CertVerifier* /* cert_verifier */)
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<>
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostResolver* host_resolver,
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CertVerifier* /* cert_verifier */)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template <>
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostResolver* host_resolver,
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CertVerifier* cert_verifier)
548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : SSLClientSocketPool(0,
549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          0,
550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          host_resolver,
552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          cert_verifier,
553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
555a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          NULL,
556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          std::string(),
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL) {}
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper functions for validating that AuthChallengeInfo's are correctly
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// configured for common cases.
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_challenge)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(auth_challenge->is_proxy);
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("MyRealm1", auth_challenge->realm);
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", auth_challenge->scheme);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_challenge)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(auth_challenge->is_proxy);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("MyRealm1", auth_challenge->realm);
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", auth_challenge->scheme);
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_challenge)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(auth_challenge->is_proxy);
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("digestive", auth_challenge->realm);
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("digest", auth_challenge->scheme);
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_challenge)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(auth_challenge->is_proxy);
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(), auth_challenge->realm);
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("ntlm", auth_challenge->scheme);
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Basic) {
6118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
6138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SimpleGET) {
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", out.response_data);
6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Response with no status line.
6327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", out.response_data);
6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Allow up to 4 bytes of junk to precede status line.
6477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("DATA", out.response_data);
6575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
6585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Allow up to 4 bytes of junk to precede status line.
6627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("DATA", out.response_data);
6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Beyond 4 bytes of slop and it should fail to find a status line.
6777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
6875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
6885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
6927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\n"),
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\n"),
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Q"),
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("J"),
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("DATA", out.response_data);
7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
7075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Close the connection before enough bytes to have a status line.
7117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTT"),
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTT", out.response_data);
7215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
7225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Simulate a 204 response, lacking a Content-Length header, sent over a
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// persistent connection.  The response should still terminate since a 204
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cannot have a response body.
7287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StopsReading204) {
7295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  char junk[] = "junk";
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
7325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead(junk),  // Should not be read!!
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
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 204 No Content", out.status_line);
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", out.response_data);
7405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
7415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 response_size = reads_size - strlen(junk);
7425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(response_size, out.totalReceivedBytes);
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A simple request using chunked encoding with some extra data after.
7467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
7475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string final_chunk = "0\r\n\r\n";
7485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string extra_data = "HTTP/1.1 200 OK\r\n";
7495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string last_read = final_chunk + extra_data;
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("5\r\nHello\r\n"),
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("1\r\n"),
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(" \r\n"),
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("5\r\nworld\r\n"),
7565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead(last_read.data()),
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello world", out.response_data);
7645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
7655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 response_size = reads_size - extra_data.size();
7665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(response_size, out.totalReceivedBytes);
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Next tests deal with http://crbug.com/56344.
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       MultipleContentLengthHeadersNoTransferEncoding) {
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n"),
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       DuplicateContentLengthHeadersNoTransferEncoding) {
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n"),
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello", out.response_data);
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ComplexContentLengthHeadersNoTransferEncoding) {
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // More than 2 dupes.
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads[] = {
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 200 OK\r\n"),
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n"),
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n"),
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n\r\n"),
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Hello"),
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                arraysize(data_reads));
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, out.rv);
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("Hello", out.response_data);
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HTTP/1.0
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads[] = {
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n"),
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n"),
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n\r\n"),
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Hello"),
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                arraysize(data_reads));
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, out.rv);
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("Hello", out.response_data);
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2 dupes and one mismatched.
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads[] = {
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 200 OK\r\n"),
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10\r\n"),
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10\r\n"),
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n\r\n"),
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                arraysize(data_reads));
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       MultipleContentLengthHeadersTransferEncoding) {
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 666\r\n"),
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 1337\r\n"),
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Transfer-Encoding: chunked\r\n\r\n"),
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("5\r\nHello\r\n"),
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("1\r\n"),
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(" \r\n"),
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("5\r\nworld\r\n"),
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello world", out.response_data);
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Next tests deal with http://crbug.com/98895.
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that a single Content-Disposition header results in no error.
8687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello", out.response_data);
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two identical Content-Disposition headers result in no error.
8837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       TwoIdenticalContentDispositionHeaders) {
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello", out.response_data);
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two distinct Content-Disposition headers result in an error.
9007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two identical Location headers result in no error.
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Also tests Location header behavior.
9157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Redirect\r\n"),
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://good.com/\r\n"),
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://good.com/\r\n"),
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://redirect.com/");
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
944868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsRedirect(&url));
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://good.com/", url);
949f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(response->proxy_server.IsEmpty());
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two distinct Location headers result in an error.
9537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Redirect\r\n"),
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://good.com/\r\n"),
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://evil.com/\r\n"),
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Do a request using the HEAD method. Verify that we don't try to read the
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// message body (since HEAD has none).
9687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Head) {
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "HEAD";
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("HEAD / HTTP/1.1\r\n"
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 404 Not Found\r\n"),
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Server: Blah\r\n"),
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 1234\r\n\r\n"),
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No response body because the test stops reading here.
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the headers got parsed.
1009868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1234, response->headers->GetContentLength());
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
1012f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(response->proxy_server.IsEmpty());
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string server_header;
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* iter = NULL;
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_server_header = response->headers->EnumerateHeader(
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &iter, "Server", &server_header);
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(has_server_header);
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Blah", server_header);
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reading should give EOF right away, since there is no message body
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (despite non-zero content-length).
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", response_data);
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
1030c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("world"),
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1040c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kExpectedResponseData[] = {
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "hello", "world"
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; ++i) {
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/");
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
1053868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1066868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response->headers.get() != NULL);
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1068f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_TRUE(response->proxy_server.IsEmpty());
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string response_data;
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ReadTransaction(trans.get(), &response_data);
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kExpectedResponseData[i], response_data);
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Ignores100) {
10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(new UploadBytesElementReader("foo", 3));
108068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.upload_data_stream = &upload_data_stream;
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1099c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test is almost the same as Ignores100 above, but the response contains
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HTTP/1.1 and the two status headers are read in one read.
11247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
11328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "HTTP/1.1 200 OK\r\n\r\n"),
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
11718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0),
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", response_data);
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
12028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0),
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockWrite* write_failure,
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockRead* read_failure) {
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
1229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
1230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Written data for successfully sending both requests.
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data1_writes[] = {
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.foo.com\r\n"
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.foo.com\r\n"
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read results for the first request.
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data1_reads[] = {
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (write_failure) {
125023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ASSERT_FALSE(read_failure);
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data1_writes[1] = *write_failure;
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(read_failure);
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data1_reads[2] = *read_failure;
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data1_writes, arraysize(data1_writes));
1259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data2_reads[] = {
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("world"),
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kExpectedResponseData[] = {
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "hello", "world"
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 first_socket_log_id = NetLog::Source::kInvalidId;
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; ++i) {
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
1278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LoadTimingInfo load_timing_info;
12872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
12892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i == 0) {
12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      first_socket_log_id = load_timing_info.socket_log_id;
12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // The second request should be using a new socket.
12932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
12942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
12952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response->headers.get() != NULL);
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string response_data;
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ReadTransaction(trans.get(), &response_data);
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kExpectedResponseData[i], response_data);
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
130923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
131023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const MockWrite* write_failure,
1311effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const MockRead* read_failure,
1312effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    bool use_spdy) {
131323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  HttpRequestInfo request;
131423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  request.method = "GET";
1315effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  request.url = GURL("https://www.foo.com/");
131623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  request.load_flags = 0;
131723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
131823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  CapturingNetLog net_log;
131923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  session_deps_.net_log = &net_log;
132023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
132123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1322effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  SSLSocketDataProvider ssl1(ASYNC, OK);
1323effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  SSLSocketDataProvider ssl2(ASYNC, OK);
1324effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (use_spdy) {
1325effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ssl1.SetNextProto(GetParam());
1326effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ssl2.SetNextProto(GetParam());
1327effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
1328effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1329effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
1330effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1331effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // SPDY versions of the request and response.
1332effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1333effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1334effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<SpdyFrame> spdy_response(
1335effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1336effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<SpdyFrame> spdy_data(
1337effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
1338effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1339effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // HTTP/1.1 versions of the request and response.
1340effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1341effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      "Host: www.foo.com\r\n"
1342effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      "Connection: keep-alive\r\n\r\n";
1343effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1344effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const char kHttpData[] = "hello";
1345effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1346effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<MockRead> data1_reads;
1347effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<MockWrite> data1_writes;
134823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (write_failure) {
134923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ASSERT_FALSE(read_failure);
1350effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data1_writes.push_back(*write_failure);
1351effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data1_reads.push_back(MockRead(ASYNC, OK));
135223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  } else {
135323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ASSERT_TRUE(read_failure);
1354effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (use_spdy) {
1355effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      data1_writes.push_back(CreateMockWrite(*spdy_request));
1356effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    } else {
1357effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      data1_writes.push_back(MockWrite(kHttpRequest));
1358effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
1359effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data1_reads.push_back(*read_failure);
136023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
136123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1362effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1363effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                 &data1_writes[0], data1_writes.size());
136423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
136523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1366effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<MockRead> data2_reads;
1367effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<MockWrite> data2_writes;
1368effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1369effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (use_spdy) {
1370effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1371effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1372effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1373effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1374effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_reads.push_back(MockRead(ASYNC, OK, 3));
1375effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  } else {
1376effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_writes.push_back(
1377effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1378effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1379effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_reads.push_back(
1380effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1381effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1382effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_reads.push_back(MockRead(ASYNC, OK, 3));
1383effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
1384effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  OrderedSocketData data2(&data2_reads[0], data2_reads.size(),
1385effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                          &data2_writes[0], data2_writes.size());
138623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
138723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
138823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Preconnect a socket.
138923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  net::SSLConfig ssl_config;
139023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  session->ssl_config_service()->GetSSLConfig(&ssl_config);
1391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session->GetNextProtos(&ssl_config.next_protos);
139223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  session->http_stream_factory()->PreconnectStreams(
139323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
139423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Wait for the preconnect to complete.
139523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // TODO(davidben): Some way to wait for an idle socket count might be handy.
139623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  base::RunLoop().RunUntilIdle();
1397effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
139823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
139923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Make the request.
140023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  TestCompletionCallback callback;
140123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
140223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
140323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
140423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
140523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
140623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
140723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
140823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  rv = callback.WaitForResult();
140923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_EQ(OK, rv);
141023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
141123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  LoadTimingInfo load_timing_info;
141223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1413effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  TestLoadTimingNotReused(
1414effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      load_timing_info,
1415effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
141623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
141723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
141823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
141923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
142023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
142123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
142223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
142323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  std::string response_data;
142423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
142523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_EQ(OK, rv);
1426effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(kHttpData, response_data);
142723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
142823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
14297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       KeepAliveConnectionNotConnectedOnWrite) {
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeepAliveConnectionResendRequestTest(&write_failure, NULL);
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeepAliveConnectionResendRequestTest(NULL, &read_failure);
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead read_failure(SYNCHRONOUS, OK);  // EOF
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeepAliveConnectionResendRequestTest(NULL, &read_failure);
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
144546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Make sure that on a 408 response (Request Timeout), the request is retried,
144646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// if the socket was a reused keep alive socket.
144746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
144846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  MockRead read_failure(SYNCHRONOUS,
144946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "HTTP/1.1 408 Request Timeout\r\n"
145046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "Connection: Keep-Alive\r\n"
145146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "Content-Length: 6\r\n\r\n"
145246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "Pickle");
145346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  KeepAliveConnectionResendRequestTest(NULL, &read_failure);
145446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
145546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
145623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
145723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)       PreconnectErrorNotConnectedOnWrite) {
145823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1459effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(&write_failure, NULL, false);
146023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
146123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
146223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
146323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1464effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(NULL, &read_failure, false);
146523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
146623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
146723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
146823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  MockRead read_failure(SYNCHRONOUS, OK);  // EOF
1469effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1470effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
1471effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1472effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1473effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MockRead read_failure(ASYNC, OK);  // EOF
1474effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1475effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
1476effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
147746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Make sure that on a 408 response (Request Timeout), the request is retried,
147846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// if the socket was a preconnected (UNUSED_IDLE) socket.
147946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
148046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  MockRead read_failure(SYNCHRONOUS,
148146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "HTTP/1.1 408 Request Timeout\r\n"
148246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "Connection: Keep-Alive\r\n"
148346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "Content-Length: 6\r\n\r\n"
148446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "Pickle");
148546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  KeepAliveConnectionResendRequestTest(NULL, &read_failure);
148646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  PreconnectErrorResendRequestTest(NULL, &read_failure, false);
148746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
148846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1489effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(HttpNetworkTransactionTest,
1490effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch       SpdyPreconnectErrorNotConnectedOnWrite) {
1491effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1492effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1493effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
1494effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1495effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1496effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1497effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1498effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
1499effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1500effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1501effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MockRead read_failure(SYNCHRONOUS, OK);  // EOF
1502effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1503effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
1504effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1505effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1506effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MockRead read_failure(ASYNC, OK);  // EOF
1507effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(NULL, &read_failure, true);
150823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
150923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
15107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
15188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_CONNECTION_RESET),
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response == NULL);
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// What do various browsers do when the server closes a non-keepalive
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection without sending any response header or body?
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IE7: error page
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Safari 3.1.2 (Windows): error page
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Firefox 3.0.1: blank page
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Opera 9.52: after five attempts, blank page
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Us: error page (EMPTY_RESPONSE)
15507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),  // EOF
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test that network access can be deferred and resumed.
15635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
15645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  HttpRequestInfo request;
15655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.method = "GET";
15665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
15675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.load_flags = 0;
15685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
15715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Defer on OnBeforeNetworkStart.
15745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BeforeNetworkStartHandler net_start_handler(true);  // defer
15755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  trans->SetBeforeNetworkStartCallback(
15765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
15775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(&net_start_handler)));
15785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MockRead data_reads[] = {
15805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
15815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
15825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead("hello"),
15835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead(SYNCHRONOUS, 0),
15845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
15855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
15865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
15875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestCompletionCallback callback;
15895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
15925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
15935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Should have deferred for network start.
15955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(net_start_handler.observed_before_network_start());
15965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
15975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(trans->GetResponseInfo() == NULL);
15985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
15995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  trans->ResumeNetworkStart();
16005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rv = callback.WaitForResult();
16015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(OK, rv);
16025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(trans->GetResponseInfo() != NULL);
16035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
16055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
16065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
16075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    rv = callback.WaitForResult();
16085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(5, rv);
16095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  trans.reset();
16105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
16115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test that network use can be deferred and canceled.
16135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
16145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  HttpRequestInfo request;
16155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.method = "GET";
16165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
16175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.load_flags = 0;
16185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
16215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Defer on OnBeforeNetworkStart.
16245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BeforeNetworkStartHandler net_start_handler(true);  // defer
16255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  trans->SetBeforeNetworkStartCallback(
16265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
16275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(&net_start_handler)));
16285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestCompletionCallback callback;
16305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
16325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
16335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
16345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Should have deferred for network start.
16365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(net_start_handler.observed_before_network_start());
16375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
16385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(trans->GetResponseInfo() == NULL);
16395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
16405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// tests. There was a bug causing HttpNetworkTransaction to hang in the
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destructor in such situations.
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See http://crbug.com/154712 and http://crbug.com/156609.
16457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1653868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: keep-alive\r\n"),
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, 0),
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1674868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, rv);
1678868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
168290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1694868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: keep-alive\r\n"),
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, 0),
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1714868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
172090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we correctly reuse a keep-alive connection after not explicitly
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reading the body.
17267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
1733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
1734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that because all these reads happen in the same
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // StaticSocketDataProvider, it shows that the same socket is being reused for
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // all transactions.
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data1_reads[] = {
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Found\r\n"
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 0\r\n\r\n"),
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Found\r\n"
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 5\r\n\r\n"
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "hello"),
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 301 Moved Permanently\r\n"
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 0\r\n\r\n"),
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 301 Moved Permanently\r\n"
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 5\r\n\r\n"
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "hello"),
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
1757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data2_reads[] = {
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kNumUnreadBodies = arraysize(data1_reads) - 2;
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_lines[kNumUnreadBodies];
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 first_socket_log_id = NetLog::Source::kInvalidId;
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
1773868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LoadTimingInfo load_timing_info;
17822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
17832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i == 0) {
17842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
17852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      first_socket_log_id = load_timing_info.socket_log_id;
17862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
17872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestLoadTimingReused(load_timing_info);
17882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
17892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
17902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1794868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ASSERT_TRUE(response->headers.get() != NULL);
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_lines[i] = response->headers->GetStatusLine();
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We intentionally don't read the response bodies.
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kStatusLines[] = {
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 204 No Content",
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 205 Reset Content",
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 304 Not Modified",
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 302 Found",
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 302 Found",
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 301 Moved Permanently",
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 301 Moved Permanently",
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 forgot_to_update_kStatusLines);
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kNumUnreadBodies; ++i)
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kStatusLines[i], response_lines[i]);
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
18172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1818868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
1825868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello", response_data);
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth.
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (basic auth is the easiest to mock, because it has no randomness).
18357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuth) {
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog log;
1842c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &log;
18438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
18458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Give a couple authenticate options (only the middle one is actually
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // supported).
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Large content-length -- won't matter, as connection will be reset.
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10000\r\n\r\n"),
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), this is the request we should
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be issuing -- the final header line contains the credentials.
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
1887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
1888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
18992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
19002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
19012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
19035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
19045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
19192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
19202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
19212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The load timing after restart should have a new socket ID, and times after
19222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // those of the first load timing.
19232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info1.receive_headers_end,
19242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info2.connect_timing.connect_start);
19252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
19262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
19285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
19295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
19448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Large content-length -- won't matter, as connection will be reset.
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10000\r\n\r\n"),
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
1963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, rv);
19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
19735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
19745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection.
19827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog log;
1989c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &log;
1990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 14\r\n\r\n"),
20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Unauthorized\r\n"),
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly, the server responds with the actual content.
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("Hello"),
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If there is a regression where we disconnect a Keep-Alive
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection during an auth roundtrip, we'll end up reading this.
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NULL, 0);
2029c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
2030c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2035868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
20432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
20442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
20452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
20602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
20612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info2);
20622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The load timing after restart should have the same socket ID, and times
20632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // those of the first load timing.
20642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info1.receive_headers_end,
20652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info2.send_start);
20662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
20672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
20725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
20735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string response_data;
20745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
20755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(OK, rv);
20765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
20775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection and with no response body to drain.
20827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2088c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly, the server responds with the actual content.
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An incorrect reconnect would cause this to be read.
21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NULL, 0);
2124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
2125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection and with a large response body to drain.
21587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Respond with 5 kb of response body.
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string large_body_string("Unauthorized");
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  large_body_string.append(5 * 1024, ' ');
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  large_body_string.append("\r\n");
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 5134 = 12 + 5 * 1024 + 2
21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5134\r\n\r\n"),
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly, the server responds with the actual content.
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An incorrect reconnect would cause this to be read.
22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NULL, 0);
2208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
2209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection, but the server gets impatient and closes the connection.
22427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This simulates the seemingly successful write to a closed connection
22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // if the bug is not fixed.
22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 14\r\n\r\n"),
22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Tell MockTCPClientSocket to simulate the server closing the connection.
22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Unauthorized\r\n"),
22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),  // The server closes the connection.
22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), this is the request we should
22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be issuing -- the final header line contains the credentials.
22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
2294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
2295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a connection
23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that requires a restart when setting up an SSL tunnel.
23287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the no authentication data flag is set.
23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
2336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
23372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No credentials.
23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Connection: close\r\n\r\n"),
23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, "hello"),
23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2404868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
24102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CONNECT requests and responses are handled at the connect job level, so
24112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the transaction does not yet have a connection.
24122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
24132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
24352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
24362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
24372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// proxy connection, when setting up an SSL tunnel.
24447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that proxy authentication is attempted even
24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the no authentication data flag is set.
24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
2453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No credentials.
24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("0123456789"),
24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Wrong credentials (wrong password).
24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No response body because the test stops reading here.
24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2515868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
25165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
25175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
25185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, response->headers->GetContentLength());
25195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
25215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
25235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wrong password (should be "bar").
25255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBaz), callback2.callback());
25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2534868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
25355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
25365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
25375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, response->headers->GetContentLength());
25385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
25395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
25405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Flush the idle socket before the NetLog and HttpNetworkTransaction go
25425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // out of scope.
25435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
25445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we don't read the response body when we fail to establish a tunnel,
25475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// even if the user cancels the proxy's auth attempt.
25487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
25495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
25515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
25525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
25535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
2555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
25565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
25585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2560868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
25615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
25635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
25645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
25655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
25665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
25675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
25685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 407.
25705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
25715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
25725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
25735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
25745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
25755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
25765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
25785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
2579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
25805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
25825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
25845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
25855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
25875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
25885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
25905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
25915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
25935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
25945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, response->headers->GetContentLength());
25955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
25965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
25985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
26005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
26025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
26035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
26065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
26077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
26085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
26105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
26125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We are using a DIRECT connection (i.e. no proxy) for this session.
26148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
26155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
26168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
26175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
26195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
26205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
26225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
26235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
26255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
26265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
26275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Large content-length -- won't matter, as connection will be reset.
26285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10000\r\n\r\n"),
26295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
26305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
26315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
26335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
26355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
26375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
26395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
26405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
26425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
26465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// through a non-authenticating proxy. The request should fail with
26475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ERR_UNEXPECTED_PROXY_AUTH.
26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that it is impossible to detect if an HTTP server returns a 407 through
26495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a non-authenticating proxy - there is nothing to indicate whether the
26505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// response came from the proxy or the server, so it is treated as if the proxy
26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// issued the challenge.
26527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       HttpsServerRequestsProxyAuthThroughProxy) {
26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
26555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
26595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
26645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
26665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
26685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
26705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
26715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
26735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
26755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Unauthorized\r\n"),
26785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\r\n"),
26805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
26815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
26825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
26845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2692868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
26935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
26955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
26965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
26985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
27025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
27035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
27045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
27085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test the load timing for HTTPS requests with an HTTP proxy.
27117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
27122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
27132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
27142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("https://www.google.com/1");
27152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
27172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
27182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("https://www.google.com/2");
27192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against proxy server "myproxy:70".
2721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
27222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixed("PROXY myproxy:70"));
27232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
2724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
27262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
27282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite data_writes1[] = {
27292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
27302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
27312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
27322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET /1 HTTP/1.1\r\n"
27342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
27352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
27362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET /2 HTTP/1.1\r\n"
27382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
27392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
27402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
27412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
27432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // connection.
27442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead data_reads1[] = {
27452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
27462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
27482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Length: 1\r\n\r\n"),
27492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, "1"),
27502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
27522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Length: 2\r\n\r\n"),
27532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, "22"),
27542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
27552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
27572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
27592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
27612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback1;
27632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans1(
2764868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
27652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans1->Start(&request1, callback1.callback(), log.bound());
27672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
27682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback1.WaitForResult();
27702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
27712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
27732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response1 != NULL);
2774868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response1->headers.get() != NULL);
27752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, response1->headers->GetContentLength());
27762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
27782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
27792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
27802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans1.reset();
27822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback2;
27842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
2785868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
27862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback2.callback(), log.bound());
27882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
27892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback2.WaitForResult();
27912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
27922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
27942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response2 != NULL);
2795868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response2->headers.get() != NULL);
27962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, response2->headers->GetContentLength());
27972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
27992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
28002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info2);
28012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
28032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans2.reset();
28052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  session->CloseAllConnections();
28062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
28072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
28097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
28102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
28112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
28122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("https://www.google.com/1");
28132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
28152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
28162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("https://www.google.com/2");
28172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against proxy server "myproxy:70".
2819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
28202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
28212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
2822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
28242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
28262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite data_writes1[] = {
28272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
28282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
28292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
28302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET /1 HTTP/1.1\r\n"
28322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
28332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
28342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET /2 HTTP/1.1\r\n"
28362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
28372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
28382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
28392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
28412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // connection.
28422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead data_reads1[] = {
28432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
28442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
28462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Length: 1\r\n\r\n"),
28472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, "1"),
28482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
28502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Length: 2\r\n\r\n"),
28512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, "22"),
28522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
28532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
28552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
28572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
28592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback1;
28612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans1(
2862868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
28632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans1->Start(&request1, callback1.callback(), log.bound());
28652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
28662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback1.WaitForResult();
28682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
28692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
28712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response1 != NULL);
2872868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response1->headers.get() != NULL);
28732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, response1->headers->GetContentLength());
28742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
28762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
28772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info1,
28782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
28792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans1.reset();
28812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback2;
28832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
2884868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
28852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback2.callback(), log.bound());
28872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
28882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback2.WaitForResult();
28902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
28912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
28932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response2 != NULL);
2894868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response2->headers.get() != NULL);
28952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, response2->headers->GetContentLength());
28962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
28982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
28992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReusedWithPac(load_timing_info2);
29002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
29022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans2.reset();
29042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  session->CloseAllConnections();
29052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
29062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a simple get through an HTTPS Proxy.
29087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
29095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
29105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
29115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
29125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
2914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
29155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
29165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
29195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should use full url
29215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
29225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
29235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
29245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
29255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
29265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
29285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
29295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
29305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
29315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
29325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
29335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
29355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
29375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
29395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
29415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2943868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
29445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
29465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
29475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
29495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
29505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
29522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
29532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
29542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
29552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
29575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
29585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
29605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
29615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
29625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
29635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
29655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
29665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY get through an HTTPS Proxy.
29697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
29705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
29715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
29725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
29735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
29745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
2976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
29775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
29785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
29815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetch http://www.google.com/ via SPDY
298390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
298490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
29855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
29865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
29887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
29895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
29905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
29915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data),
29925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
29935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
29945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
29965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
29975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
29985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
2999c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
30005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
30027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
30045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
30065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3008868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
30095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
30115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
30125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
30145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
30155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
30172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
30182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
30192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
30202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
30225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
3023868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
30245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
30255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
30275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
30285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUploadData, response_data);
30295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
30305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// Verifies that a session which races and wins against the owning transaction
30326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// (completing prior to host resolution), doesn't fail the transaction.
30336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// Regression test for crbug.com/334413.
30346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
30356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  HttpRequestInfo request;
30366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  request.method = "GET";
30376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
30386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  request.load_flags = 0;
30396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Configure SPDY proxy server "proxy:70".
30416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.proxy_service.reset(
30426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      ProxyService::CreateFixed("https://proxy:70"));
30436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  CapturingBoundNetLog log;
30446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
30456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
30466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Fetch http://www.google.com/ through the SPDY proxy.
30486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_ptr<SpdyFrame> req(
30496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
30506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  MockWrite spdy_writes[] = {CreateMockWrite(*req)};
30516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
30536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
30546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  MockRead spdy_reads[] = {
30556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      CreateMockRead(*resp), CreateMockRead(*data), MockRead(ASYNC, 0, 0),
30566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  };
30576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  DelayedSocketData spdy_data(
30596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      1,  // wait for one write to finish before reading.
30606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      spdy_reads,
30616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      arraysize(spdy_reads),
30626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      spdy_writes,
30636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      arraysize(spdy_writes));
30646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
30656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
30676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ssl.SetNextProto(GetParam());
30686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
30696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  TestCompletionCallback callback1;
30716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
30736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
30746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Stall the hostname resolution begun by the transaction.
30766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.host_resolver->set_synchronous_mode(false);
30776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.host_resolver->set_ondemand_mode(true);
30786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
30806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
30816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Race a session to the proxy, which completes first.
30836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.host_resolver->set_ondemand_mode(false);
30846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  SpdySessionKey key(
30856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
30866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  base::WeakPtr<SpdySession> spdy_session =
30876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      CreateSecureSpdySession(session, key, log.bound());
30886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Unstall the resolution begun by the transaction.
30906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.host_resolver->set_ondemand_mode(true);
30916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.host_resolver->ResolveAllPending();
30926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_FALSE(callback1.have_result());
30946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  rv = callback1.WaitForResult();
30956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_EQ(OK, rv);
30966d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
30986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
30996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
31006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
31016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  std::string response_data;
31036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
31046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_EQ(kUploadData, response_data);
31056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
31066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY get through an HTTPS Proxy.
31087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
31095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
31105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
31115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
31125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
31135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
3115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
31165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://myproxy:70"));
31175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
31205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first request will be a bare GET, the second request will be a
31225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GET with a Proxy-Authorization header.
31235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> req_get(
312490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
31255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kExtraAuthorizationHeaders[] = {
312690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "proxy-authorization", "Basic Zm9vOmJhcg=="
31275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
31285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> req_get_authorization(
312990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
313090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  arraysize(kExtraAuthorizationHeaders) / 2,
313190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  false,
313290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  3,
313390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  LOWEST,
313490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  false));
31355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
31365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req_get, 1),
31375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req_get_authorization, 4),
31385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
31395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first response is a 407 proxy authentication challenge, and the second
31415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // response will be a 200 response since the second request includes a valid
31425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Authorization header.
31435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kExtraAuthenticationHeaders[] = {
314490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "proxy-authenticate", "Basic realm=\"MyRealm1\""
31455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
31465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp_authentication(
31477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdySynReplyError(
31485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "407 Proxy Authentication Required",
31495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
31505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          1));
31515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> body_authentication(
31527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
31537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp_data(
31547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
31557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
31565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
31575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp_authentication, 2),
31585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body_authentication, 3),
31595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp_data, 5),
31605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body_data, 6),
31615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 7),
31625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
31635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data(
31655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
31665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
31685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
31707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
31725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
31745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
31775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
31795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
31805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
31825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
31835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* const response = trans->GetResponseInfo();
31855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
3187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
31885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
31895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
31905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
31915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
31935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
31955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
31965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
31975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
31995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
32005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
32025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response_restart != NULL);
3204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response_restart->headers.get() != NULL);
32055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response_restart->headers->response_code());
32065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
32075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
32085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
32117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
32125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
32135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
32145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
32155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
32165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
3218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
32195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
32205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
32235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
32265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY
32283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
32293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                LOWEST));
32305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetch https://www.google.com/ via HTTP
32315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char get[] = "GET / HTTP/1.1\r\n"
32335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Host: www.google.com\r\n"
32345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Connection: keep-alive\r\n\r\n";
32355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get(
32367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
32377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp(
32387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
32395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char resp[] = "HTTP/1.1 200 OK\r\n"
32405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 10\r\n\r\n";
32415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp(
32427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
32435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body(
32447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
32455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> window_update(
324690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
32475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
32495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*connect, 1),
32505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*wrapped_get, 3),
325190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      CreateMockWrite(*window_update, 5),
32525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
32535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
32555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_resp, 2, ASYNC),
32565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_get_resp, 4, ASYNC),
32575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body, 6, ASYNC),
32585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body, 7, ASYNC),
32595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 8),
32605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
32615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
32635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
32645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
32665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
32687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
32705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
32715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl2.was_npn_negotiated = false;
32725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl2.protocol_negotiated = kProtoUnknown;
3273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
32745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
32765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
32785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
32795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
32815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
32825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
32842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
32852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
32862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
32875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
32885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
3289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
32905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
32915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
32935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
32945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("1234567890", response_data);
32955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
32987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
32995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
33005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
33015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
33025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
33035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
3305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
33065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
33075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
33105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
33135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY
33153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
33163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                LOWEST));
33175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetch https://www.google.com/ via SPDY
33185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kMyUrl = "https://www.google.com/";
331990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> get(
332090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
33217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get(
33227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(get, 1));
33237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp(
33247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
33257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> get_resp(
33267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
33275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp(
33287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
33297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
33307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body(
33317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(body, 1));
33325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> window_update_get_resp(
333390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
33345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> window_update_body(
333590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
33365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
33385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*connect, 1),
33395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*wrapped_get, 3),
33405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*window_update_get_resp, 5),
33415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*window_update_body, 7),
33425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
33435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
33455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_resp, 2, ASYNC),
33465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_get_resp, 4, ASYNC),
33475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body, 6, ASYNC),
33485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 8),
33495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
33505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
33525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
33535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
33555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
33577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
33595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
33607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
33617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.protocol_negotiated = GetParam();
3362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
33635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
33655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
33675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
33685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
33705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
33715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
33732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
33742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
33752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
33775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
3378868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
33795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
33805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
33825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
33835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUploadData, response_data);
33845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
33855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY CONNECT failure through an HTTPS Proxy.
33877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
33885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
33895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
33905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
33915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
33925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
3394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
33955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
33965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
33995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
34025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY
34043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
34053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                LOWEST));
340690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> get(
340790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
34085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
34105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*connect, 1),
34115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*get, 3),
34125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
34135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
34157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
34165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
34175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp, 2, ASYNC),
34185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 4),
34195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
34205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
34225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
34235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
34255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
34277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
34295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
34307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
3431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
34325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
34345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
34365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
34375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
34395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
34405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(ttuttle): Anything else to check here?
34425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
34452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// HTTPS Proxy to different servers.
34467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
34472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
34482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against https proxy server "proxy:70".
3449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
34502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "https://proxy:70"));
34512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
3452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
34532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
3454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
34552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
34572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
34582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("https://www.google.com/");
34592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.load_flags = 0;
34602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
34622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
34632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("https://news.google.com/");
34642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.load_flags = 0;
34652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY.
34673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
34683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                 LOWEST));
34697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp1(
34707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
34712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fetch https://www.google.com/ via HTTP.
34732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char get1[] = "GET / HTTP/1.1\r\n"
34742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Host: www.google.com\r\n"
34752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Connection: keep-alive\r\n\r\n";
34762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get1(
34777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
34782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char resp1[] = "HTTP/1.1 200 OK\r\n"
34792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Content-Length: 1\r\n\r\n";
34802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp1(
34817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
34827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body1(
34837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
34842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> window_update(
348590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
34862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CONNECT to news.google.com:443 via SPDY.
3488c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SpdySynStreamIR connect2_ir(3);
3489c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  spdy_util_.SetPriority(LOWEST, &connect2_ir);
3490c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  connect2_ir.SetHeader(spdy_util_.GetMethodKey(), "CONNECT");
3491c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  connect2_ir.SetHeader(spdy_util_.GetPathKey(), "news.google.com:443");
3492c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  connect2_ir.SetHeader(spdy_util_.GetHostKey(), "news.google.com");
3493c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  spdy_util_.MaybeAddVersionHeader(&connect2_ir);
34942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> connect2(
3495c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      spdy_util_.CreateFramer(false)->SerializeFrame(connect2_ir));
3496c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
34977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp2(
34987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
34992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fetch https://news.google.com/ via HTTP.
35012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char get2[] = "GET / HTTP/1.1\r\n"
35022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Host: news.google.com\r\n"
35032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Connection: keep-alive\r\n\r\n";
35042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get2(
35057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
35062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char resp2[] = "HTTP/1.1 200 OK\r\n"
35072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Content-Length: 2\r\n\r\n";
35082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp2(
35097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
35102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body2(
35117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
35122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite spdy_writes[] = {
35142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*connect1, 0),
35152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*wrapped_get1, 2),
35162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*connect2, 5),
35172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*wrapped_get2, 7),
35182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
35192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead spdy_reads[] = {
35212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*conn_resp1, 1, ASYNC),
35222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
35232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_body1, 4, ASYNC),
35242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*conn_resp2, 6, ASYNC),
35252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
35262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_body2, 9, ASYNC),
35272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 0, 10),
35282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
35292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeterministicSocketData spdy_data(
35312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
35322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
35342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
35367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
35382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
35392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl2.was_npn_negotiated = false;
35402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl2.protocol_negotiated = kProtoUnknown;
3541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
35422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl3(ASYNC, OK);
35432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl3.was_npn_negotiated = false;
35442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl3.protocol_negotiated = kProtoUnknown;
3545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
35462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
35482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3550868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
35512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
35522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
35532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The first connect and request, each of their responses, and the body.
35542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(5);
35552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
35572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
35582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
35602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
35612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
35622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
35642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
3565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
35662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
35672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string response_data;
35692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3570868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
35712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
3573868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
35742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
35752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
35762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The second connect and request, each of their responses, and the body.
35782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(5);
35792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
35802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
35812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
35832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
35842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Even though the SPDY connection is reused, a new tunnelled connection has
35852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to be created, so the socket's load timing looks like a fresh connection.
35862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
35872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The requests should have different IDs, since they each are using their own
35892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // separate stream.
35902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
35912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3592868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
35932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
35942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
35962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// HTTPS Proxy to the same server.
35977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
35982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
35992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against https proxy server "proxy:70".
3600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
36012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "https://proxy:70"));
36022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
3603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
36042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
3605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
36062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
36082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
36092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("https://www.google.com/");
36102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.load_flags = 0;
36112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
36132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
36142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("https://www.google.com/2");
36152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.load_flags = 0;
36162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY.
36183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
36193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                 LOWEST));
36207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp1(
36217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
36222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fetch https://www.google.com/ via HTTP.
36242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char get1[] = "GET / HTTP/1.1\r\n"
36252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Host: www.google.com\r\n"
36262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Connection: keep-alive\r\n\r\n";
36272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get1(
36287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
36292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char resp1[] = "HTTP/1.1 200 OK\r\n"
36302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Content-Length: 1\r\n\r\n";
36312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp1(
36327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
36337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body1(
36347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
36352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> window_update(
363690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
36372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fetch https://www.google.com/2 via HTTP.
36392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char get2[] = "GET /2 HTTP/1.1\r\n"
36402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Host: www.google.com\r\n"
36412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Connection: keep-alive\r\n\r\n";
36422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get2(
36437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
36442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char resp2[] = "HTTP/1.1 200 OK\r\n"
36452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Content-Length: 2\r\n\r\n";
36462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp2(
36477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
36482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body2(
36497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
36502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite spdy_writes[] = {
36522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*connect1, 0),
36532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*wrapped_get1, 2),
36542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*wrapped_get2, 5),
36552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
36562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead spdy_reads[] = {
36582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*conn_resp1, 1, ASYNC),
36592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
36602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_body1, 4, ASYNC),
36612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
36622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_body2, 7, ASYNC),
36632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 0, 8),
36642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
36652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeterministicSocketData spdy_data(
36672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
36682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
36702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
36727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
36742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
36752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl2.was_npn_negotiated = false;
36762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl2.protocol_negotiated = kProtoUnknown;
3677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
36782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
36802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
36832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
36842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
36852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The first connect and request, each of their responses, and the body.
36862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(5);
36872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
36892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
36902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
36922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
36932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
36942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
36962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
3697868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
36982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
36992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string response_data;
37012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3702868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
37032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans.reset();
37042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
3706868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
37072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
37082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
37092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The second request, response, and body.  There should not be a second
37112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // connect.
37122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(3);
37132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
37142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
37152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
37172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
37182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info2);
37192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The requests should have the same ID.
37212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
37222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3723868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
37242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
37252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
37272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Proxy to different servers.
37287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
37292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       HttpsProxySpdyLoadTimingTwoHttpRequests) {
37302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against https proxy server "proxy:70".
3731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
37322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "https://proxy:70"));
37332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
3734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
37352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
3736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
37372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
37392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
37402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("http://www.google.com/");
37412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.load_flags = 0;
37422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
37442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
37452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("http://news.google.com/");
37462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.load_flags = 0;
37472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // http://www.google.com/
37497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> headers(
37507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
3751a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<SpdyFrame> get1(spdy_util_.ConstructSpdyControlFrame(
37527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
37537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> get_resp1(
37547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
37557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(
37567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
37572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // http://news.google.com/
37597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> headers2(
37607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
3761a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<SpdyFrame> get2(spdy_util_.ConstructSpdyControlFrame(
37627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      headers2.Pass(), false, 3, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
37637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> get_resp2(
37647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
37657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(
37667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
37672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite spdy_writes[] = {
37692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*get1, 0),
37702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*get2, 3),
37712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
37722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead spdy_reads[] = {
37742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*get_resp1, 1, ASYNC),
37752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*body1, 2, ASYNC),
37762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*get_resp2, 4, ASYNC),
37772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*body2, 5, ASYNC),
37782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 0, 6),
37792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
37802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeterministicSocketData spdy_data(
37822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
37832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
37852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
37877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
37892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
37912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3793868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
37942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
37952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
37962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(2);
37972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
37992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
38002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
38022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
38032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
38042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
38052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
38072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
3808868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
38092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
38102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string response_data;
38122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3813868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
38142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(1);
38152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, callback.WaitForResult());
38162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Delete the first request, so the second one can reuse the socket.
38172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans.reset();
38182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
3820868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
38212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
38222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
38232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(2);
38252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
38262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
38272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
38292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
38302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info2);
38312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The requests should have the same ID.
38332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
38342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3835868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
38362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(1);
38372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, callback.WaitForResult());
38382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
38392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the challenge-response-retry sequence through an HTTPS Proxy
38417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
38425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
38435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
38445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
38455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the no authentication data flag is set.
38465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
38475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
3849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
38505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://myproxy:70"));
38515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
38545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should use full url
38565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
38575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
38585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
38595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
38605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
38625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
38635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
38645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
38655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
38665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
38675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
38685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the GET with a 407, using a persistent
38705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
38715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
38725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No credentials.
38735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
38745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
38755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Connection: keep-alive\r\n"),
38765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
38775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
38795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
38805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
38815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
38825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
38835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
38855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
3886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
38875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
3888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
38895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
38915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3893868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
38945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
38965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
38975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
38995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
39005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
39022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
39032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
39042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
39052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
39075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
3908868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
39095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
39105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
39115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
39125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
39145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
39165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
39175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
39185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
39205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
39215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  load_timing_info = LoadTimingInfo();
39232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
39242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Retrying with HTTP AUTH is considered to be reusing a socket.
39252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info);
39262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
39285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
39295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
39315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
39325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
39335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
39345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
39365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
39375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
39385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
39405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockRead& status, int expected_status) {
39415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
39425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
39435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
39445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
39455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
3947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
3948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
39495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
39515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
39525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
39535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
39545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
39555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
39565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
39585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status,
39595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
39605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No response body because the test stops reading here.
39615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
39625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
39635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
39655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
3966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
39675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
39695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3971868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
39725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
39745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
39755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
39775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_status, rv);
39785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
39795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::ConnectStatusHelper(
39815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockRead& status) {
39825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelperWithExpectedStatus(
39835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      status, ERR_TUNNEL_CONNECTION_FAILED);
39845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
39855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
39875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
39885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
39895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
39915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
39925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
39935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
39955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
39965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
39975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
39995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
40005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
40035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(
40045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
40055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
40085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
40095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
40125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
40135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
40165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
40175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
40205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
40215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
40245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
40255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
40285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
40295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
40325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
40335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
40365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
40375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
40405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
40415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
40445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
40455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
40485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
40495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
40525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
40535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
40545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
40557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
40565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
40575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
40605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
40615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
40645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
40655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
40685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
40695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
40725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
40735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
40765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
40775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
40805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
40815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
40845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelperWithExpectedStatus(
40855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
40865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ERR_PROXY_AUTH_UNSUPPORTED);
40875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
40905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
40915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
40945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
40955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
40985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
40995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
41025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
41035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
41065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
41075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
41105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
41115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
41145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
41155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
41185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
41195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
41225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(
41235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
41245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
41275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
41285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
41315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
41325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
41355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
41365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
41395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
41405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
41435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
41445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
41475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
41485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
41515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
41525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the flow when both the proxy server AND origin server require
41555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// authentication. Again, this uses basic auth for both since that is
41565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the simplest to mock.
41577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
41585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
41595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
41605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
41615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
41625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Configure against proxy server "myproxy:70".
4164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
41658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
41665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
41688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
41695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
41715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
41725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
41735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
41745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
41755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
41775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 407 Unauthorized\r\n"),
41785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Give a couple authenticate options (only the middle one is actually
41795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // supported).
41805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic invalid\r\n"),  // Malformed.
41815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
41825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
41835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
41845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Large content-length -- won't matter, as connection will be reset.
41855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10000\r\n\r\n"),
41865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
41875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
41885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth() the first time, this is the
41905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // request we should be issuing -- the final header line contains the
41915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // proxy's credentials.
41925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
41935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
41945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
41955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
41965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
41975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
41985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now the proxy server lets the request pass through to origin server.
42005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The origin server responds with a 401.
42015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
42025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
42035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note: We are using the same realm-name as the proxy server. This is
42045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // completely valid, as realms are unique across hosts.
42055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
42065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
42075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 2000\r\n\r\n"),
42085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),  // Won't be reached.
42095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth() the second time, we should send
42125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the credentials for both the proxy and origin server.
42135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes3[] = {
42145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
42155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
42165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
42175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
42185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
42195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly we get the desired content.
42225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads3[] = {
42235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
42245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
42255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
42265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
42275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
42305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
42315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
42325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
42335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
42345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
4235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
4236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
4237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
42385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
42405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
42425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
42435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
42455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
42465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
42485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
42495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
42505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
42525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
42545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
42555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
42565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
42585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
42595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
42615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
42625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
42635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
42655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
42675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo2, kBar2), callback3.callback());
42685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
42695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
42715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
42725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
42745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
42755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
42765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
42775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For the NTLM implementation using SSPI, we skip the NTLM tests since we
42795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can't hook into its internals to cause it to generate predictable NTLM
42805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// authorization headers.
42815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NTLM_PORTABLE)
42825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The NTLM authentication unit tests were generated by capturing the HTTP
42835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// requests and responses using Fiddler 2 and inspecting the generated random
42845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bytes in the debugger.
42855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Enter the correct password and authenticate successfully.
42877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
42885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
42895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
42905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://172.22.68.17/kids/login.aspx");
42914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
42924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Ensure load is not disrupted by flags which suppress behaviour specific
42934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // to other auth schemes.
42944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
42955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
42975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    MockGetHostName);
4298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
42995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
43015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
43025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
43035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
43045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
43055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
43075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
43085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Negotiate and NTLM are often requested together.  However, we only want
43095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
43105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the header that requests Negotiate for this test.
43115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM\r\n"),
43125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: close\r\n"),
43135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
43145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
43155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Missing content -- won't matter, as connection will be reset.
43165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
43175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
43185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
43205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After restarting with a null identity, this is the
43215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // request we should be issuing -- the final header line contains a Type
43225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1 message.
43235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
43245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
43255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
43265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM "
43275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
43285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), we should send a Type 3 message
43305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (the credentials for the origin server).  The second request continues
43315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // on the same connection.
43325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
43335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
43345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
43355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
43365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
43375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
43385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
43395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "ahlhx5I=\r\n\r\n"),
43405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
43415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
43435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The origin server responds with a Type 2 message.
43445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
43455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM "
43465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
43475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
43485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
43495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
43505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
43515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
43525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "BtAAAAAAA=\r\n"),
43535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
43545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
43555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("You are not authorized to view this page\r\n"),
43565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly we get the desired content.
43585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
43595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=utf-8\r\n"),
43605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 13\r\n\r\n"),
43615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Please Login\r\n"),
43625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
43635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
43645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
43665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
43675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
43685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
4369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
4370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
43715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
43735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
43765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
43785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
43795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
43815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
43825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
43845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
43865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(response == NULL);
43875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
43885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
43905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
43925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              callback2.callback());
43935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
43945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
43965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
43975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
43995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
44015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
44025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
44035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
44055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
44075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
44085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
44105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
44115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
44135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
44145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
44155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(13, response->headers->GetContentLength());
44165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
44175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Enter a wrong password, and then the correct one.
44197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
44205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
44215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
44225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://172.22.68.17/kids/login.aspx");
44235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
44245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
44265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    MockGetHostName);
4427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
44285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
44305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
44315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
44325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
44335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
44345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
44365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
44375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Negotiate and NTLM are often requested together.  However, we only want
44385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
44395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the header that requests Negotiate for this test.
44405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM\r\n"),
44415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: close\r\n"),
44425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
44435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
44445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Missing content -- won't matter, as connection will be reset.
44455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
44465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
44475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
44495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After restarting with a null identity, this is the
44505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // request we should be issuing -- the final header line contains a Type
44515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1 message.
44525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
44535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
44545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
44555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM "
44565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
44575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), we should send a Type 3 message
44595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (the credentials for the origin server).  The second request continues
44605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // on the same connection.
44615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
44625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
44635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
44645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
44655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
44665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
44675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
44685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "4Ww7b7E=\r\n\r\n"),
44695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
44705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
44725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The origin server responds with a Type 2 message.
44735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
44745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM "
44755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
44765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
44775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
44785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
44795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
44805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
44815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "BtAAAAAAA=\r\n"),
44825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
44835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
44845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("You are not authorized to view this page\r\n"),
44855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Wrong password.
44875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
44885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM\r\n"),
44895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: close\r\n"),
44905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
44915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
44925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Missing content -- won't matter, as connection will be reset.
44935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
44945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
44955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes3[] = {
44975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After restarting with a null identity, this is the
44985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // request we should be issuing -- the final header line contains a Type
44995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1 message.
45005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
45015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
45025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
45035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM "
45045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
45055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), we should send a Type 3 message
45075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (the credentials for the origin server).  The second request continues
45085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // on the same connection.
45095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
45105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
45115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
45125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
45135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
45145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
45155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
45165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "+4MUm7c=\r\n\r\n"),
45175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
45185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads3[] = {
45205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The origin server responds with a Type 2 message.
45215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
45225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM "
45235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
45245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
45255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
45265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
45275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
45285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
45295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "BtAAAAAAA=\r\n"),
45305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
45315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
45325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("You are not authorized to view this page\r\n"),
45335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly we get the desired content.
45355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
45365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=utf-8\r\n"),
45375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 13\r\n\r\n"),
45385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Please Login\r\n"),
45395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
45405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
45415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
45435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
45445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
45455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
45465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
45475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
4548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
4549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
4550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
45515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
45535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
45565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
45585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
45595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
45615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
45625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
45645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
45665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
45675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
45685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
45705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enter the wrong password.
45725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
45735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              callback2.callback());
45745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
45755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
45775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
45785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
45805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
45815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
45825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
45835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
45845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
45855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
45865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
45885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(response == NULL);
45895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
45905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback4;
45925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now enter the right password.
45945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
45955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              callback4.callback());
45965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
45975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback4.WaitForResult();
45995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
46005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
46025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback5;
46045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // One more roundtrip
46065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
46075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
46085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback5.WaitForResult();
46105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
46115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
46135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
46145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(13, response->headers->GetContentLength());
46155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
46165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // NTLM_PORTABLE
46175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test reading a server response which has only headers, and no body.
46195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// After some maximum number of bytes is consumed, the transaction should
46205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
46217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
46225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
46235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
46245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
46255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
46265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
46285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
46298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
46305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Respond with 300 kb of headers (we should fail after 256 kb).
46325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string large_headers_string;
46335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FillLargeHeadersString(&large_headers_string, 300 * 1024);
46345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
46365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
46375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
46385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\r\nBODY"),
46395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
46405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
46415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
46435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
46455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
46475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
46485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
46505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
46515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
46535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response == NULL);
46545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
46555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that we don't try to reuse a TCPClientSocket when failing to
46575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// establish tunnel.
46585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/chromium/issues/detail?id=3772
46597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
46605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       DontRecycleTransportSocketForSSLTunnel) {
46615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
46625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
46635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
46645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
46655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
4667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
46685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
46705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4672868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
46735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
46755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
46765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
46775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
46785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
46795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
46805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 404, using a persistent
46825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection. Usually a proxy would return 501 (not implemented),
46835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or 200 (tunnel established).
46845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
46855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 404 Not Found\r\n"),
46865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
46875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
46885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
46895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
46915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
4692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
46935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
46955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
46975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
46985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
47005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
47015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
47035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response == NULL);
47045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
47065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
470790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
47085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the TCPClientSocket was not added back to
47105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the pool.
4711868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
47125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
471390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
47145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure that the socket didn't get recycled after calling the destructor.
4715868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
47165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
47175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that we recycle a socket after reading all of the response body.
47197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
47205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
47215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
47225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
47235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
47245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
47265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4728868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
47295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
47315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // A part of the response body is received with the response headers.
47325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
47335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The rest of the response body is received in two parts.
47345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("lo"),
47355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(" world"),
47365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("junk"),  // Should not be read!!
47375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
47385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
47425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
47445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
47465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
47475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
47495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
47505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
47525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
47535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4754868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
47555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string status_line = response->headers->GetStatusLine();
47565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", status_line);
47575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4758868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
47595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
47615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
47625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
47635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
47645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
47665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
476790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
47685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4770868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
47715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
47725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that we recycle a SSL socket after reading all of the response
47745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// body.
47757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
47765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
47775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
47785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
47795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
47805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
47825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
47835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
47845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
47855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
47885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
47895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 11\r\n\r\n"),
47905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
47915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
47925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
4795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
47965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
47985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
4799c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
48005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
48025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4803c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
48042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4805868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
48065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
48085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
48105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
48115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
48135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
4814868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
48155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
48165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4817868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
48185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
48205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
48215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
48225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
48235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
48255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
482690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
48275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4829868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
48305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
48315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Grab a SSL socket, use it, and put it back into the pool.  Then, reuse it
48335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from the pool and make sure that we recover okay.
48347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
48355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
48365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
48375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
48385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
48395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
48415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
48425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
48435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
48445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
48455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
48465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
48475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
48485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
48505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
48515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 11\r\n\r\n"),
48525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
48535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
48545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0)   // EOF
48555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
48565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
48585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
4859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
48615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
48635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
48645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
48655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
4866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
4867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
48685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
48705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
48722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4873868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
48745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
48765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
48785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
48795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
48815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
4882868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
48835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
48845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
48865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
48885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
48895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
48905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
48915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
48935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
489490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
48955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4897868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
48985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now start the second transaction, which should reuse the previous socket.
49005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4901868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
49025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
49045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
49065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
49075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
49095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
4910868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
49115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
49125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4913868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
49145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
49165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
49175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
49185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
49205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
492190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
49225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4924868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
49255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
49265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that we recycle a socket after a zero-length response.
49285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/9880
49297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
49305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
49315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
49325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
49335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
49345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     "e=17259,18167,19592,19773,19981,20133,20173,20233&"
49355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     "rt=prt.2642,ol.2649,xjs.2951");
49365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
49375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
49395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4941868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
49425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
49445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 204 No Content\r\n"
49455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 0\r\n"
49465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Type: text/html\r\n\r\n"),
49475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("junk"),  // Should not be read!!
49485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
49495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
49505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
49535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
49555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
49575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
49585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
49605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
49615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
49635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
49645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4965868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
49665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string status_line = response->headers->GetStatusLine();
49675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
49685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4969868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
49705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
49725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
49735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
49745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", response_data);
49755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
49775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
497890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
49795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4981868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
49825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
49835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
49852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
49862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(new UploadBytesElementReader("foo", 3));
498768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
49882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
49895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request[2];
49905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 1: a GET request that succeeds.  The socket is recycled
49915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // after use.
49925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[0].method = "GET";
49935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[0].url = GURL("http://www.google.com/");
49945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[0].load_flags = 0;
49955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 2: a POST request.  Reuses the socket kept alive from
49965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction 1.  The first attempts fails when writing the POST data.
49975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This causes the transaction to retry with a new socket.  The second
49985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // attempt succeeds.
49995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[1].method = "POST";
50005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[1].url = GURL("http://www.google.com/login.cgi");
50012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request[1].upload_data_stream = &upload_data_stream;
50025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[1].load_flags = 0;
50035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5004c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
50055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first socket is used for transaction 1 and the first attempt of
50075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction 2.
50085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The response of transaction 1.
50105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
50115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
50125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
50135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
50145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
50155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The mock write results of transaction 1 and the first attempt of
50165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction 2.
50175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
50185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 64),  // GET
50195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 93),  // POST
50205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED),  // POST data
50215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
50225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
50235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
50245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The second socket is used for the second attempt of transaction 2.
50265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The response of transaction 2.
50285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
50295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
50305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("welcome"),
50315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
50325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
50335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The mock write results of the second attempt of transaction 2.
50345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
50355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 93),  // POST
50365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 3),  // POST data
50375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
50385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
50395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
50405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5041c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
5042c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
50435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kExpectedResponseData[] = {
50455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "hello world", "welcome"
50465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
50475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; ++i) {
50495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5050868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
50515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
50535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
50555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
50565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
50585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
50595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
50615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
50625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5063868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response->headers.get() != NULL);
50645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
50655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string response_data;
50675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ReadTransaction(trans.get(), &response_data);
50685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
50695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kExpectedResponseData[i], response_data);
50705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
50715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
50725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth when there is
50745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// an identity in the URL. The request should be sent as normal, but when
50755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it fails the identity from the URL is used to answer the challenge.
50767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
50775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
50785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
50795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://foo:b@r@www.google.com/");
50805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = LOAD_NORMAL;
50815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
50835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
50848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
50855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password contains an escaped character -- for this test to pass it
50875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will need to be unescaped by HttpNetworkTransaction.
50885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("b%40r", request.url.password());
50895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
50915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
50925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
50935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
50945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
50955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
50975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
50985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
50995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
51005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
51015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
51025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the challenge above, the transaction will be restarted using the
51045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // identity from the url (foo, b@r) to answer the challenge.
51055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
51065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
51075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
51085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
51095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
51105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
51115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
51135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
51145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
51155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
51165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
51175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
51195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
51205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
51215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
5122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
5123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
51245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
51265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
51275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
51285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
51295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
51305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
51315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
51335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
51345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
51355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
51365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
51375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
51385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
51405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
51415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There is no challenge info, since the identity in URL worked.
51435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
51445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
51465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.
514890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
51495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
51505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth when there is an
51525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// incorrect identity in the URL. The identity from the URL should be used only
51535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// once.
51547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
51555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
51565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
51575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: the URL has a username:password in it.  The password "baz" is
51585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // wrong (should be "bar").
51595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://foo:baz@www.google.com/");
51605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = LOAD_NORMAL;
51625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
51645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
51658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
51665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
51685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
51695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
51705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
51715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
51725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
51745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
51755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
51765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
51775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
51785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
51795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the challenge above, the transaction will be restarted using the
51815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // identity from the url (foo, baz) to answer the challenge.
51825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
51835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
51845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
51855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
51865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
51875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
51885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
51905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
51915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
51925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
51935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
51945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
51955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the challenge above, the transaction will be restarted using the
51975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // identity supplied by the user (foo, bar) to answer the challenge.
51985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes3[] = {
51995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
52005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
52015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
52025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
52035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
52045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads3[] = {
52065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
52075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
52085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
52095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
52105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
52125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
52135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
52145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
52155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
52165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
5217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
5218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
5219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
52205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
52225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
52245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
52255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
52275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
52285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
52305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
52315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
52325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
52335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
52345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
52355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
52365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
52385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
52395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
52405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
52425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
52435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback3.callback());
52445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
52455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
52465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
52475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
52485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
52505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
52515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There is no challenge info, since the identity worked.
52535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
52545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
52565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.
525890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
52595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
52605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
52624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Test the request-challenge-retry sequence for basic auth when there is a
52634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// correct identity in the URL, but its use is being suppressed. The identity
52644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// from the URL should never be used.
52654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
52664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  HttpRequestInfo request;
52674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.method = "GET";
52684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.url = GURL("http://foo:bar@www.google.com/");
52694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
52704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
52718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
52724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
52738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
52744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
52754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MockWrite data_writes1[] = {
52764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
52774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Host: www.google.com\r\n"
52784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
52794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
52804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
52814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MockRead data_reads1[] = {
52824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
52834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
52844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
52854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
52864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
52874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
52884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // After the challenge above, the transaction will be restarted using the
52894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // identity supplied by the user, not the one in the URL, to answer the
52904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // challenge.
52914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MockWrite data_writes3[] = {
52924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
52934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Host: www.google.com\r\n"
52944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Connection: keep-alive\r\n"
52954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
52964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
52974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
52984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MockRead data_reads3[] = {
52994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
53004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
53014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
53024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
53034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
53054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
53064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
53074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
53084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
53094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
53104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestCompletionCallback callback1;
53124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
53134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
53144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  rv = callback1.WaitForResult();
53154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(OK, rv);
53164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
53174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
53194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
53204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
53214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestCompletionCallback callback3;
53234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  rv = trans->RestartWithAuth(
53244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      AuthCredentials(kFoo, kBar), callback3.callback());
53254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
53264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  rv = callback3.WaitForResult();
53274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(OK, rv);
53284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
53294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  response = trans->GetResponseInfo();
53314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
53324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // There is no challenge info, since the identity worked.
53344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
53354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
53364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Empty the current queue.
53384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
53394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
53404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that previously tried username/passwords for a realm get re-used.
53427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
5343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
53445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 1: authenticate (foo, bar) on MyRealm1
53465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
53475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
53485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
53495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/z");
53505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
53515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
53545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
53565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z HTTP/1.1\r\n"
53575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
53585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n\r\n"),
53595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
53605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
53625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
53635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
53645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
53655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
53665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
53675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization (username=foo, password=bar)
53695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
53705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z HTTP/1.1\r\n"
53715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
53725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
53735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
53745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
53755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
53775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
53785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
53795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
53805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
53815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
53825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
53845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
53855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
53865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
5387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
53895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
53915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
53935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
53945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
53965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
53975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
53995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
54005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
54015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
54035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(
54055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AuthCredentials(kFoo, kBar), callback2.callback());
54065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
54075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
54095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
54105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response = trans->GetResponseInfo();
54125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
54135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
54145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
54155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
54165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
54185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 2: authenticate (foo2, bar2) on MyRealm2
54205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
54215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
54225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
54235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note that Transaction 1 was at /x/y/z, so this is in the same
54245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // protection space as MyRealm1.
54255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/a/b");
54265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
54275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5429868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
54305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
54325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
54335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
54345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
54355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // Send preemptive authorization for MyRealm1
54365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
54375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
54385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The server didn't like the preemptive authorization, and
54405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // challenges us for a different realm (MyRealm2).
54415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
54425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
54435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
54445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
54455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
54465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
54475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
54495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
54505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
54515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
54525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
54535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
54545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
54555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
54575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
54585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
54595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
54605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
54615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
54625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
54645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
54655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
54665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
5467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
54695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
54715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
54735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
54745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
54765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
54775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
54795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
54805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response->auth_challenge.get());
54815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(response->auth_challenge->is_proxy);
54825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("www.google.com:80",
54835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              response->auth_challenge->challenger.ToString());
54845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
54855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("basic", response->auth_challenge->scheme);
54865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
54885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(
54905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AuthCredentials(kFoo2, kBar2), callback2.callback());
54915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
54925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
54945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
54955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response = trans->GetResponseInfo();
54975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
54985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
54995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
55005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
55015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
55035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 3: Resend a request in MyRealm's protection space --
55055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // succeed with preemptive authorization.
55065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
55075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
55085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
55095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/z2");
55105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
55115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5513868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
55145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
55165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
55175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
55185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
55195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // The authorization for MyRealm1 gets sent preemptively
55205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // (since the url is in the same protection space)
55215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
55225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
55235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the preemptive authorization
55255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
55265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
55275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
55285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
55295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
55305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
55325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
5533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
55345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
55365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
55385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
55395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
55415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
55425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
55445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
55455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
55475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
55485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
55495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
55515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 4: request another URL in MyRealm (however the
55535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // url is not known to belong to the protection space, so no pre-auth).
55545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
55555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
55565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
55575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/1");
55585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
55595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5561868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
55625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
55645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/1 HTTP/1.1\r\n"
55655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
55665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n\r\n"),
55675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
55685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
55705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
55715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
55725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
55735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
55745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
55755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization from MyRealm's cache.
55775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
55785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/1 HTTP/1.1\r\n"
55795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
55805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
55815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
55825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
55835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
55855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
55865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
55875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
55885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
55895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
55905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
55925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
55935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
55945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
5595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
55975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
55995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
56015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
56025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
56045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
56055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(trans->IsReadyToRestartForAuth());
56075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
56085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
56095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
56105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
56115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
56125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(trans->IsReadyToRestartForAuth());
56135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
56155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
56165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
56175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
56185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
56195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
56215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 5: request a URL in MyRealm, but the server rejects the
56235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cached identity. Should invalidate and re-prompt.
56245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
56255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
56265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
56275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/p/q/t");
56285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
56295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5631868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
56325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
56345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /p/q/t HTTP/1.1\r\n"
56355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
56365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n\r\n"),
56375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
56405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
56415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
56425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
56435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
56445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization from cache for MyRealm.
56475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
56485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /p/q/t HTTP/1.1\r\n"
56495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
56505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
56515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
56525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever rejects the authorization.
56555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
56565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
56575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
56585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
56595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
56605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // At this point we should prompt for new credentials for MyRealm.
56635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Restart with username=foo3, password=foo4.
56645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes3[] = {
56655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /p/q/t HTTP/1.1\r\n"
56665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
56675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
56685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
56695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
56725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads3[] = {
56735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
56745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
56755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
56765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
56795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
56805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
56815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
56825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
56835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes3, arraysize(data_writes3));
5684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
5686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data3);
56875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
56895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
56915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
56925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
56945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
56955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(trans->IsReadyToRestartForAuth());
56975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
56985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
56995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
57005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
57015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
57025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(trans->IsReadyToRestartForAuth());
57035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
57055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
57065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
57075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback3;
57095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(
57115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AuthCredentials(kFoo3, kBar3), callback3.callback());
57125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
57135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback3.WaitForResult();
57155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
57165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response = trans->GetResponseInfo();
57185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
57195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
57205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
57215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
57225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
57235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that nonce count increments when multiple auth attempts
57255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are started with the same nonce.
57267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
57275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerDigest::Factory* digest_factory =
57285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new HttpAuthHandlerDigest::Factory();
57295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
57305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
57315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  digest_factory->set_nonce_generator(nonce_generator);
5732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.http_auth_handler_factory.reset(digest_factory);
5733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
57345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 1: authenticate (foo, bar) on MyRealm1
57365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
57375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
57385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
57395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/z");
57405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
57415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5743868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
57445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
57465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z HTTP/1.1\r\n"
57475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
57485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n\r\n"),
57495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
57505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
57525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
57535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
57545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
57555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
57565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
57575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization (username=foo, password=bar)
57595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
57605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z HTTP/1.1\r\n"
57615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
57625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
57635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Digest username=\"foo\", realm=\"digestive\", "
57645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
57655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
57665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
57675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
57685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
57705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
57715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
57725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
57735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
57745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
57765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
57775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
57785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
5779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
57815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
57835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
57855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
57865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
57885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
57895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
57915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
57925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
57935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
57955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(
57975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AuthCredentials(kFoo, kBar), callback2.callback());
57985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
57995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
58015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
58025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response = trans->GetResponseInfo();
58045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
58055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
58065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
58075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
58095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 2: Request another resource in digestive's protection space.
58115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This will preemptively add an Authorization header which should have an
58125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "nc" value of 2 (as compared to 1 in the first use.
58135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
58145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
58155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
58165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note that Transaction 1 was at /x/y/z, so this is in the same
58175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // protection space as digest.
58185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/a/b");
58195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
58205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5822868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
58235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
58255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
58265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
58275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
58285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Digest username=\"foo\", realm=\"digestive\", "
58295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
58305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
58315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
58325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
58335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
58355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
58365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
58375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
58385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
58395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
58405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
58425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
5843c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
58445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
58465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
58485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
58495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
58515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
58525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
58545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
58555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
58565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
58575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
58585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the ResetStateForRestart() private method.
58607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
58615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a transaction (the dependencies aren't important).
58628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
58635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans(
58648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
58655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setup some state (which we expect ResetStateForRestart() will clear).
58675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans->read_buf_ = new IOBuffer(15);
58685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans->read_buf_len_ = 15;
58695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans->request_headers_.SetHeader("Authorization", "NTLM");
58705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setup state in response_
58725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpResponseInfo* response = &trans->response_;
58735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->auth_challenge = new AuthChallengeInfo();
58745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->ssl_info.cert_status = static_cast<CertStatus>(-1);  // Nonsensical.
58755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->response_time = base::Time::Now();
58765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->was_cached = true;  // (Wouldn't ever actually be true...)
58775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { // Setup state for response_.vary_data
58795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
58805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
58815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::replace(temp.begin(), temp.end(), '\n', '\0');
58825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
58835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.extra_headers.SetHeader("Foo", "1");
58845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.extra_headers.SetHeader("bar", "23");
5885868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
58865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
58875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cause the above state to be reset.
58895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans->ResetStateForRestart();
58905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the state that needed to be reset, has been reset.
58925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->read_buf_.get() == NULL);
58935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, trans->read_buf_len_);
58945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->request_headers_.IsEmpty());
58955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
58965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() == NULL);
58975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_cached);
58985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, response->ssl_info.cert_status);
58995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->vary_data.is_valid());
59005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
59015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections to a site with a bad certificate
59037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
59045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
59055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
59065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
59075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
59085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
59105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
59118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
59125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
59145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
59155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
59165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
59175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
59185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
59205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
59215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
59225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
59235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
59245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
59255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider ssl_bad_certificate;
59275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
59285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
59295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
59305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
59315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
5934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
59365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
59385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
59405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
59415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
59435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
59445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartIgnoringLastError(callback.callback());
59465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
59475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
59495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
59505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
59525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
59545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
59555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
59565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections to a site with a bad certificate, going through a
59585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// proxy
59597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
5960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
59615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
59635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
59645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
59655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
59665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite proxy_writes[] = {
59685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
59695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
59705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
59715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
59725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead proxy_reads[] = {
59745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
59755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
59765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
59775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
59795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
59805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
59815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
59825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
59835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
59845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
59855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
59865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
59885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
59895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
59905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
59915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
59925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
59935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
59945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider ssl_bad_certificate(
59965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      proxy_reads, arraysize(proxy_reads),
59975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      proxy_writes, arraysize(proxy_writes));
59985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
59995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
60005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
60015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
60025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6004c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
60075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
60095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; i++) {
6011c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->ResetNextMockIndexes();
60125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
60145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
60158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
60165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
60185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
60195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
60215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
60225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartIgnoringLastError(callback.callback());
60245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
60255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
60275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
60285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
60305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
60325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
60335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
60345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
60355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections to a site, going through an HTTPS proxy
60387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
6039c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
60402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
60412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
6042c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
60435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
60455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
60465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
60475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
60485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
60505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
60515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
60525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
60535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
60545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
60555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
60565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
60575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
60595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
60605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
60615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
60625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
60635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
60645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
60655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
60675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
60685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
60695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider tunnel_ssl(ASYNC, OK);  // SSL through the tunnel
60705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6071c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6072c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6073c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
60745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
60765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
60785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
60798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
60805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
60825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
60835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
60855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
60865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
60875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
60895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
60915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
60925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
60935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
60942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
60952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
60962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
60972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
60982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
60995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
61005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test an HTTPS Proxy's ability to redirect a CONNECT request
61027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
6103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
61042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
61052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
6106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
61075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
61095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
61105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
61115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
61125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
61145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
61155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
61165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
61175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
61185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
61205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Redirect\r\n"),
61215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://login.example.com/\r\n"),
61225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
61235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
61245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
61255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
61275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
61285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
61295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
61325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
61345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
61365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
61378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
61385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
61405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
61415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
61435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
61445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
61455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
61475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(302, response->headers->response_code());
61495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
61505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsRedirect(&url));
61515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://login.example.com/", url);
61522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
61532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // In the case of redirects from proxies, HttpNetworkTransaction returns
61542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // timing for the proxy connection instead of the connection to the host,
61552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // and no send / receive times.
61562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
61572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
61582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
61592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
61602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.socket_reused);
61612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
61622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
61632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
61642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_start,
61652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.proxy_resolve_end);
61662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_end,
61672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.connect_timing.connect_start);
61682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectConnectTimingHasTimes(
61692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      load_timing_info.connect_timing,
61702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
61712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
61722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.send_start.is_null());
61732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.send_end.is_null());
61742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
61755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
61765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
61787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
6179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
61805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://proxy:70"));
61815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
61835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
61845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
61855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
61865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
61883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                             LOWEST));
618990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> goaway(
619090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
61915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
61925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
6193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
61945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
61955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* const kExtraHeaders[] = {
61975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "location",
61985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "http://login.example.com/",
61995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(
62017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
62025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 arraysize(kExtraHeaders)/2, 1));
62035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
62045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
62055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 2),  // EOF
62065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data(
62095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
62105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads),
62115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_writes, arraysize(data_writes));
62125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
62137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy_ssl.SetNextProto(GetParam());
62145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
62175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
62195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
62215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
62228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
62235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
62255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
62265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
62285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
62295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
62305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
62325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(302, response->headers->response_code());
62345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
62355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsRedirect(&url));
62365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://login.example.com/", url);
62375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
62385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that an HTTPS proxy's response to a CONNECT request is filtered.
62407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
62415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ErrorResponseToHttpsConnectViaHttpsProxy) {
6242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
62435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://proxy:70"));
62445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
62465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
62475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
62485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
62495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
62515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
62525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
62535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
62545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
62575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 404 Not Found\r\n"),
62585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 23\r\n\r\n"),
62595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("The host does not exist"),
62605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
62615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
62645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
62655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
62665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
62695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
62715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
62735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
62748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
62755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
62775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
62785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
62805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
62815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(ttuttle): Anything else to check here?
62835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
62845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that a SPDY proxy's response to a CONNECT request is filtered.
62867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
62875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ErrorResponseToHttpsConnectViaSpdyProxy) {
6288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
6289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     ProxyService::CreateFixed("https://proxy:70"));
62905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
62925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
62935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
62945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
62955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
62973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                             LOWEST));
629890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> rst(
629990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
63005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
63015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
63025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
63035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
63045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* const kExtraHeaders[] = {
63065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "location",
63075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "http://login.example.com/",
63085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
63095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(
63107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
63115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 arraysize(kExtraHeaders)/2, 1));
63125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> body(
63137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(
63147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          1, "The host does not exist", 23, true));
63155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
63165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
63175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body.get(), 2, SYNCHRONOUS),
63185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 4),  // EOF
63195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
63205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data(
63225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
63235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads),
63245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_writes, arraysize(data_writes));
63255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
63267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy_ssl.SetNextProto(GetParam());
63275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
63305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
63325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
63345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
63358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
63365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
63385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
63395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
63415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
63425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(ttuttle): Anything else to check here?
63445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
63455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, through
63475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a SPDY proxy over a single SPDY session.
63487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
63495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
63505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
63515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
63525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the no authentication data flag is set.
63535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
63545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
6356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
63572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
63585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
6359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
6360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
63615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
63633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
63643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                            LOWEST));
636590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> rst(
636690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
63675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), this is the request we should
63695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be issuing -- the final header line contains the credentials.
63705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kAuthCredentials[] = {
63715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "proxy-authorization", "Basic Zm9vOmJhcg==",
63725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
637390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
63743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
63755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetch https://www.google.com/ via HTTP
63765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char get[] = "GET / HTTP/1.1\r\n"
63775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Host: www.google.com\r\n"
63785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Connection: keep-alive\r\n\r\n";
63795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get(
63807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
63815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
63835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req, 1, ASYNC),
63845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*rst, 4, ASYNC),
63855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*connect2, 5),
63865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*wrapped_get, 8),
63875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
63885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
63905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
63915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kAuthChallenge[] = {
63927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetStatusKey(), "407 Proxy Authentication Required",
63937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    spdy_util_.GetVersionKey(), "HTTP/1.1",
63945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "proxy-authenticate", "Basic realm=\"MyRealm1\"",
63955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
63965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_auth_resp(
6398a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      spdy_util_.ConstructSpdyControlFrame(NULL,
6399a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           0,
6400a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           false,
6401a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           1,
6402a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           LOWEST,
6403a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           SYN_REPLY,
6404a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           CONTROL_FLAG_NONE,
6405a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           kAuthChallenge,
6406a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           arraysize(kAuthChallenge),
6407a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                           0));
64085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp(
64107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
64115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char resp[] = "HTTP/1.1 200 OK\r\n"
64125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 5\r\n\r\n";
64135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp(
64157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
64165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body(
64177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
64185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
64195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_auth_resp, 2, ASYNC),
64205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_resp, 6, ASYNC),
64215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_get_resp, 9, ASYNC),
64225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body, 10, ASYNC),
64235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK, 11),  // EOF.  May or may not be read.
64245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
64255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
64275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
64285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
6429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
64305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Negotiate SPDY to the proxy
64315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy(ASYNC, OK);
64327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy.SetNextProto(GetParam());
6433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
64345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Vanilla SSL to the server
64355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider server(ASYNC, OK);
6436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
64375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
64395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
6441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
64425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
64445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
64455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
64475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
64485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
64495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
64505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
64515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
64525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
64535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
64545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
64555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
64565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
64575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
64595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
6460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
64615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
64625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
64635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() != NULL);
64645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
64655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
64675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
64695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              callback2.callback());
64705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
64715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
64735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
64745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
64765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
64775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
64795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
64805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
64815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
64825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
64845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
64855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
64872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
64882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
64892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
64902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
64915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
64925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
64935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
64945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that an explicitly trusted SPDY proxy can push a resource from an
64965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// origin that is different from that of its associated resource.
64977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
64985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
64995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo push_request;
65005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
65025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
65035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  push_request.method = "GET";
65045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  push_request.url = GURL("http://www.another-origin.com/foo.dat");
65055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
6507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
65082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
65095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
6510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
65115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable cross-origin push.
6513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.trusted_spdy_proxy = "myproxy:70";
65145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
65165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
651790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> stream1_syn(
651890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
65195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
652190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CreateMockWrite(*stream1_syn, 1, ASYNC),
65225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
65235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
65257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
65265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
65287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
65295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
65317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
65325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    0,
65335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    2,
65345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    1,
65355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    "http://www.another-origin.com/foo.dat"));
6536eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const char kPushedData[] = "pushed";
6537eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<SpdyFrame> stream2_body(
6538eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      spdy_util_.ConstructSpdyBodyFrame(
6539eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          2, kPushedData, strlen(kPushedData), true));
65405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
65425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream1_reply, 2, ASYNC),
65435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream2_syn, 3, ASYNC),
65445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream1_body, 4, ASYNC),
6545eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    CreateMockRead(*stream2_body, 5, ASYNC),
65465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
65475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
65485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
65505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
65515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
6552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
65535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Negotiate SPDY to the proxy
65545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy(ASYNC, OK);
65557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy.SetNextProto(GetParam());
6556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
65575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
6559868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
65605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
65615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), log.bound());
65625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
65635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
65655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
65665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
65675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> push_trans(
6569868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6570868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = push_trans->Start(&push_request, callback.callback(), log.bound());
65715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
65725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
65745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
65755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
65765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
65785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
65795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
65815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
65825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
65845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
65855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
65865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
65875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
65892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
65902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
65912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
65922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
65935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify the pushed stream.
6594868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(push_response->headers.get() != NULL);
65955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, push_response->headers->response_code());
65965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(push_trans.get(), &response_data);
65985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
65995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("pushed", response_data);
66005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo push_load_timing_info;
66022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
66032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReusedWithPac(push_load_timing_info);
66042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The transactions should share a socket ID, despite being for different
66052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // origins.
66062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info.socket_log_id,
66072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            push_load_timing_info.socket_log_id);
66082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
66095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
66105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  push_trans.reset();
66115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
66125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
66135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
66157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
66165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
66175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
66195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
66205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
6622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
66235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://myproxy:70"));
66245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
6625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
66265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable cross-origin push.
6628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.trusted_spdy_proxy = "myproxy:70";
66295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
66315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
663290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> stream1_syn(
663390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
66345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> push_rst(
663690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
66375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
66395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*stream1_syn, 1, ASYNC),
66405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*push_rst, 4),
66415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
66425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
66447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
66455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
66477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
66485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
66507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
66515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    0,
66525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    2,
66535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    1,
66545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    "https://www.another-origin.com/foo.dat"));
66555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
66575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream1_reply, 2, ASYNC),
66585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream2_syn, 3, ASYNC),
66595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream1_body, 5, ASYNC),
66605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
66615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
66625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
66645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
66655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
6666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
66675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Negotiate SPDY to the proxy
66685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy(ASYNC, OK);
66697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy.SetNextProto(GetParam());
6670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
66715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
6673868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
66745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
66755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), log.bound());
66765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
66775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
66795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
66805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
66815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
66835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
66845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
66865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
66875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
66895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
66905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
66915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
66925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
66945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
66955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
66965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections to a site with a bad certificate, going through an
66985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HTTPS proxy
66997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
6700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
67015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
67025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
67045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
67055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
67065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
67075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attempt to fetch the URL from a server with a bad cert
67095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite bad_cert_writes[] = {
67105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
67115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
67125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
67135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
67145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead bad_cert_reads[] = {
67165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
67175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
67185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
67195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attempt to fetch the URL with a good cert
67215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite good_data_writes[] = {
67225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
67235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
67245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
67255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
67265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
67275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
67285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
67295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead good_cert_reads[] = {
67315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
67325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
67335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
67345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
67355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
67365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
67375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider ssl_bad_certificate(
67395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bad_cert_reads, arraysize(bad_cert_reads),
67405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bad_cert_writes, arraysize(bad_cert_writes));
67415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
67425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                good_data_writes, arraysize(good_data_writes));
67435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
67445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
67455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SSL to the proxy, then CONNECT request, then SSL with bad certificate
6747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
67505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SSL to the proxy, then CONNECT request, then valid SSL certificate
6752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
67555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
67575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
67595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
67608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
67615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
67635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
67645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
67665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
67675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartIgnoringLastError(callback.callback());
67695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
67705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
67725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
67735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
67755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
67775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
67785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
67795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
67815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
67825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
67835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
67845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
67855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  "Chromium Ultra Awesome X Edition");
67865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
67885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
67898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
67905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
67925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
67935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
67945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
67955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
67965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
67975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
67995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
68005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
68015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
68025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
68035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
68045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
68075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6808c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
68095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
68115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
68135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
68145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
68165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
68175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
68185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
68205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
68215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
68225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
68235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
68245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  "Chromium Ultra Awesome X Edition");
68255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6826c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
68278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
68285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
68298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
68305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
68325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
68335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
68345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
68355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
68365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
68385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return an error, so the transaction stops here (this test isn't
68395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // interested in the rest).
68405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
68415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
68425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Connection: close\r\n\r\n"),
68435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
68465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
68485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
68505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
68525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
68535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
68555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
68565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
68575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
68595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
68605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
68615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
68625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
68635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
68645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  "http://the.previous.site.com/");
68655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
68675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
68688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
68695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
68715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
68725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
68735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
68745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Referer: http://the.previous.site.com/\r\n\r\n"),
68755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
68785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
68795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
68805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
68815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
68825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
68835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
68865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
68885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
68905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
68925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
68935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
68955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
68965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
68975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
68995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
69005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
69015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
69025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
69045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
69058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
69065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
69085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("POST / HTTP/1.1\r\n"
69095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
69105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
69115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
69125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
69155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
69165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
69175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
69185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
69195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
69205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
69235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
69255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
69275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
69295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
69305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
69325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
69335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
69345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
69365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
69375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "PUT";
69385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
69395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
69415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
69428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
69435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
69455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("PUT / HTTP/1.1\r\n"
69465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
69475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
69485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
69495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
69525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
69535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
69545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
69555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
69565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
69575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
69605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
69625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
69645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
69665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
69675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
69695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
69705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
69715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
69735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
69745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "HEAD";
69755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
69765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
69785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
69798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
69805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
69825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("HEAD / HTTP/1.1\r\n"
69835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
69845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
69855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
69865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
69895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
69905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
69915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
69925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
69935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
69945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
69975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
69995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
70015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
70035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
70045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
70065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
70075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
70085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
70105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
70115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
70125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
70135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = LOAD_BYPASS_CACHE;
70145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
70165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
70178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
70185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
70205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
70215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
70225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
70235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Pragma: no-cache\r\n"
70245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Cache-Control: no-cache\r\n\r\n"),
70255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
70265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
70285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
70295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
70305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
70315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
70325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
70335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
70345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
70365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7037c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
70385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
70405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
70425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
70435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
70455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
70465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
70475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
70495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       BuildRequest_CacheControlValidateCache) {
70505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
70515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
70525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
70535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = LOAD_VALIDATE_CACHE;
70545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
70565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
70578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
70585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
70605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
70615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
70625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
70635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Cache-Control: max-age=0\r\n\r\n"),
70645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
70655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
70675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
70685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
70695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
70705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
70715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
70725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
70735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
70755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7076c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
70775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
70795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
70815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
70825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
70845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
70855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
70865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
70885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
70895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
70905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
70915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader("FooHeader", "Bar");
70925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
70945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
70958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
70965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
70985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
70995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
71005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
71015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "FooHeader: Bar\r\n\r\n"),
71025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
71055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
71065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
71075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
71085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
71095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
71105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
71135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
71155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
71175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
71195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
71205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
71225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
71235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
71245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
71265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
71275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
71285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
71295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader("referer", "www.foo.com");
71305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader("hEllo", "Kitty");
71315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader("FoO", "bar");
71325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
71345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
71358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
71365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
71385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
71395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
71405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
71415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "referer: www.foo.com\r\n"
71425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "hEllo: Kitty\r\n"
71435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "FoO: bar\r\n\r\n"),
71445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
71475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
71485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
71495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
71505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
71515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
71525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
71555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
71575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
71595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
71615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
71625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
71645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
71655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
71665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
71685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
71695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
71705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
71715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
71725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
71742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
71752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
7176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
71775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
71795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
71808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
71815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
71835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
71845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
71865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
71875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
71885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
71895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
71905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
71935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
71945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
71955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
71965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Payload"),
71975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
71985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
72015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
72035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
72055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
72075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
72085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
72105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
72115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
72135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
72145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
72162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
72172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
72182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
72192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_text;
72215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
72225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
72235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Payload", response_text);
72245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
72255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
72275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
72285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
72295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
72305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
72315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
72332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
72342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
7235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
72365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
72385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
72398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
72405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
72425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
72435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
72455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
72465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              arraysize(write_buffer)),
72475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
72485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
72495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
72505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
72515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
72535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
72545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(read_buffer)),
72555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
72565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
72575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Payload"),
72585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
72595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
72605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
72625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
72645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
7266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
72672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
72692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
72712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
72722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
72742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
72752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
72772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
72782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
72792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
72802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
72822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
72832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string response_text;
72852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
72862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
72872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("Payload", response_text);
72882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
72892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
72912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request;
72922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.method = "GET";
72932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.url = GURL("http://www.google.com/");
72942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.load_flags = 0;
72952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
72972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixed("socks4://myproxy:1080"));
72982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
7299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
73002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
73022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
73038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
73042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
73062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
73072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite data_writes[] = {
73092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
73102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
73112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
73122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
73132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
73142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead data_reads[] = {
73162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
73172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
73182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
73192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Payload"),
73202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
73212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
73222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
73242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                data_writes, arraysize(data_writes));
7325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
73265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
73285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
73305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
73315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
73335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
73345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
73365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
73375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
73392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
73402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
73412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
73422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_text;
73445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
73455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
73465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Payload", response_text);
73475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
73485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
73505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
73515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
73525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
73535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
73545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
73562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
73572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
7358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
73595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
73615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
73628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
73635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
73655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
73665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5OkRequest[] = {
73675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x05,  // Version
73685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01,  // Command (CONNECT)
73695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00,  // Reserved.
73705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03,  // Address type (DOMAINNAME).
73715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0E,  // Length of domain (14)
73725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Domain string:
73735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
73745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x50,  // 16-bit port (80)
73755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
73765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5OkResponse[] =
73775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
73785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
73805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
73815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
73825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
73835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
73845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
73855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
73865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
73885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
73895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
73905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
73915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
73925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Payload"),
73935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
73945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
73955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
73975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
73995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
74015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
74035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
74045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
74065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
74075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
74095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
74105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
74122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
74132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
74142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
74152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
74165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_text;
74175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
74185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
74195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Payload", response_text);
74205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
74215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
74235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
74245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
74255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
74265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
74275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
74292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
74302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
7431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
74325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
74345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
74358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
74365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
74385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
74395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char kSOCKS5OkRequest[] = {
74405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x05,  // Version
74415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01,  // Command (CONNECT)
74425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00,  // Reserved.
74435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03,  // Address type (DOMAINNAME).
74445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0E,  // Length of domain (14)
74455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Domain string:
74465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
74475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01, 0xBB,  // 16-bit port (443)
74485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
74495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5OkResponse[] =
74515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
74525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
74545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
74555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
74565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              arraysize(kSOCKS5OkRequest)),
74575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
74585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
74595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
74605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
74615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
74635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
74645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
74655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
74665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
74675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Payload"),
74685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
74695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
74705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
74725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
74745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
7476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
74775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
74795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
74815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
74825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
74845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
74855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
74875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
74885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
74902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
74912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
74922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
74932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
74945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_text;
74955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
74965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
74975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Payload", response_text);
74985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
74995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
75015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that for connection endpoints the group names are correctly set.
75035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct GroupNameTest {
75055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string proxy_server;
75065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
75075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string expected_group_name;
75085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ssl;
75095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
75105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
7512eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    NextProto next_proto,
7513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SpdySessionDependencies* session_deps_) {
7514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
75155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7516ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
75175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
75185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
75195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair("host.with.alternate", 80), 443,
7520eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(next_proto));
75215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return session;
75235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
75245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GroupNameTransactionHelper(
75265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& url,
75275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const scoped_refptr<HttpNetworkSession>& session) {
75285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
75295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
75305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL(url);
75315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
75325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
7534868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
75355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
75375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We do not complete this request, the dtor will clean the transaction up.
75395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return trans->Start(&request, callback.callback(), BoundNetLog());
75405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
75415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
75435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
75455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GroupNameTest tests[] = {
75465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
75475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
75485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://www.google.com/direct",
75495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "www.google.com:80",
75505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
75515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
75525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
75535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
75545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://[2001:1418:13:1::25]/direct",
75555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "[2001:1418:13:1::25]:80",
75565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
75575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
75585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SSL Tests
75605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
75615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
75625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://www.google.com/direct_ssl",
75635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/www.google.com:443",
75645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
75655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
75665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
75675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
75685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://[2001:1418:13:1::25]/direct",
75695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/[2001:1418:13:1::25]:443",
75705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
75715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
75725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
75735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
75745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://host.with.alternate/direct",
75755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/host.with.alternate:443",
75765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
75775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
75785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
75795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7580cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
75815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.proxy_service.reset(
75845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProxyService::CreateFixed(tests[i].proxy_server));
75855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(
7586eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SetupSessionForGroupNameTests(GetParam(), &session_deps_));
75875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpNetworkSessionPeer peer(session);
75895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameTransportSocketPool* transport_conn_pool =
75905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameTransportSocketPool(NULL, NULL);
75915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameSSLSocketPool* ssl_conn_pool =
75925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameSSLSocketPool(NULL, NULL);
7593f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7594f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new MockClientSocketPoolManager);
75955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
75965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
7597f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    peer.SetClientSocketPoolManager(
7598f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        mock_pool_manager.PassAs<ClientSocketPoolManager>());
75995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING,
76015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              GroupNameTransactionHelper(tests[i].url, session));
76025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tests[i].ssl)
76035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
76045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl_conn_pool->last_group_name_received());
76055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
76065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
76075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                transport_conn_pool->last_group_name_received());
76085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
76095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
76115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
76135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GroupNameTest tests[] = {
76145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
76155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http_proxy",
76165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://www.google.com/http_proxy_normal",
76175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "www.google.com:80",
76185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
76195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
76205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SSL Tests
76225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
76235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http_proxy",
76245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://www.google.com/http_connect_ssl",
76255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/www.google.com:443",
76265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
76275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
76285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
76305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http_proxy",
76315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://host.with.alternate/direct",
76325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/host.with.alternate:443",
76335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
76345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
76352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
76362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
76372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "http_proxy",
76382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "ftp://ftp.google.com/http_proxy_normal",
76392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "ftp/ftp.google.com:21",
76402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      false,
76412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    },
76425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
76435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7644cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
76455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.proxy_service.reset(
76485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProxyService::CreateFixed(tests[i].proxy_server));
76495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(
7650eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SetupSessionForGroupNameTests(GetParam(), &session_deps_));
76515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpNetworkSessionPeer peer(session);
76535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostPortPair proxy_host("http_proxy", 80);
76555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
76565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
76575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameSSLSocketPool* ssl_conn_pool =
76585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameSSLSocketPool(NULL, NULL);
76595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7660f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7661f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new MockClientSocketPoolManager);
76625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
76635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7664f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    peer.SetClientSocketPoolManager(
7665f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        mock_pool_manager.PassAs<ClientSocketPoolManager>());
76665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING,
76685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              GroupNameTransactionHelper(tests[i].url, session));
76695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tests[i].ssl)
76705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
76715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl_conn_pool->last_group_name_received());
76725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
76735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
76745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                http_proxy_pool->last_group_name_received());
76755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
76765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
76775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
76795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GroupNameTest tests[] = {
76805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
76815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4://socks_proxy:1080",
76825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://www.google.com/socks4_direct",
76835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4/www.google.com:80",
76845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
76855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
76865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
76875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks5://socks_proxy:1080",
76885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://www.google.com/socks5_direct",
76895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks5/www.google.com:80",
76905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
76915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
76925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SSL Tests
76945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
76955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4://socks_proxy:1080",
76965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://www.google.com/socks4_ssl",
76975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4/ssl/www.google.com:443",
76985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
76995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
77005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
77015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks5://socks_proxy:1080",
77025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://www.google.com/socks5_ssl",
77035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks5/ssl/www.google.com:443",
77045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
77055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
77065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
77085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4://socks_proxy:1080",
77095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://host.with.alternate/direct",
77105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4/ssl/host.with.alternate:443",
77115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
77125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
77135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
77145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7715cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
77165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.proxy_service.reset(
77195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProxyService::CreateFixed(tests[i].proxy_server));
77205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(
7721eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SetupSessionForGroupNameTests(GetParam(), &session_deps_));
77225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpNetworkSessionPeer peer(session);
77245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostPortPair proxy_host("socks_proxy", 1080);
77265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
77275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
77285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameSSLSocketPool* ssl_conn_pool =
77295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameSSLSocketPool(NULL, NULL);
77305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7731f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7732f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new MockClientSocketPoolManager);
77335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
77345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7735f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    peer.SetClientSocketPoolManager(
7736f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        mock_pool_manager.PassAs<ClientSocketPoolManager>());
77375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
7739868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
77405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING,
77425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              GroupNameTransactionHelper(tests[i].url, session));
77435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tests[i].ssl)
77445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
77455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl_conn_pool->last_group_name_received());
77465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
77475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
77485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                socks_conn_pool->last_group_name_received());
77495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
77505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
77515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
77535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
77545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
77555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
77565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
77585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("myproxy:70;foobar:80"));
77595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This simulates failure resolving all hostnames; that means we will fail
77615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connecting to both proxies (myproxy:70 and foobar:80).
7762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
77635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
77655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
77668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
77675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
77695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
77715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
77725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
77745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
77755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
77765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Base test to make sure that when the load flags for a request specify to
77785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bypass the cache, the DNS cache is not used.
77797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
7780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int load_flags) {
77815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue a request, asking to bypass the cache(s).
77825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
77835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
77845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = load_flags;
77855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
77865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Select a host resolver that does caching.
7788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver.reset(new MockCachingHostResolver);
77895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
77918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
77928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
77935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Warm up the host cache so it has an entry for "www.google.com".
77955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList addrlist;
77965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
7797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int rv = session_deps_.host_resolver->Resolve(
77983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
77993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      DEFAULT_PRIORITY,
78003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      &addrlist,
78013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      callback.callback(),
78023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      NULL,
78033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      BoundNetLog());
78045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
78055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
78065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
78075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that it was added to host cache, by doing a subsequent async lookup
78095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and confirming it completes synchronously.
7810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  rv = session_deps_.host_resolver->Resolve(
78113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
78123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      DEFAULT_PRIORITY,
78133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      &addrlist,
78143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      callback.callback(),
78153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      NULL,
78163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      BoundNetLog());
78175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, rv);
78185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Inject a failure the next time that "www.google.com" is resolved. This way
78205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we can tell if the next lookup hit the cache, or the "network".
78215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (cache --> success, "network" --> failure).
7822c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
78235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
78255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // first read -- this won't be reached as the host resolution will fail first.
78265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
78275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7828c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
78295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run the request.
78315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
78325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, rv);
78335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
78345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we bypassed the cache, we would have gotten a failure while resolving
78365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "www.google.com".
78375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
78385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
78395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There are multiple load flags that should trigger the host cache bypass.
78415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test each in isolation:
78427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
78435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
78445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
78455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
78475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
78485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
78495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
78515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
78525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
78535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure we can handle an error when writing the request.
78557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
78565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
78575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
78585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
78595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
78605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite write_failure[] = {
78625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, ERR_CONNECTION_RESET),
78635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
78645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(NULL, 0,
78655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                write_failure, arraysize(write_failure));
7866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
78678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
78685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
78705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
78728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
78735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
78755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
78765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
78785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
78795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
78805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that a connection closed after the start of the headers finishes ok.
78827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
78835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
78845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
78855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
78865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
78875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
78895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1."),
78905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
78915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
78925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
78958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
78965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
78985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
79008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
79015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
79035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
79045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
79065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
79075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
79095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
79105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7911868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
79125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
79135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
79155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
79165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
79175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", response_data);
79185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
79195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that a dropped connection while draining the body for auth
79215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// restart does the right thing.
79227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
79235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
79245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
79255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
79265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
79275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
79295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
79305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
79315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
79325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
79335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
79355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
79365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
79375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
79385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 14\r\n\r\n"),
79395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Unauth"),
79405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_CONNECTION_RESET),
79415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
79425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
79445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
7945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
79465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), this is the request we should
79485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be issuing -- the final header line contains the credentials.
79495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
79505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
79515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
79525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
79535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
79545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
79555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
79575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
79585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
79595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
79605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
79615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
79625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
79635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
79655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
7966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
79678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
79685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
79705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
7972868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
79735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
79755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
79765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
79785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
79795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
79815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
79825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
79835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
79855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
79875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
79885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
79895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
79915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
79925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
79945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
79955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
79965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
79975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
79985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections going through a proxy that sends extra data.
80007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
8001c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
80025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
80045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
80055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
80065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
80075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead proxy_reads[] = {
80095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
80105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
80115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
80125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
80145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
80155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8016c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
8017c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
80185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
80205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8021c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->ResetNextMockIndexes();
80225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
80245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
80258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
80265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
80285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
80295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
80315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
80325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
80335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
80355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
80365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
80375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
80385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
80395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
80415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
80428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
80435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
80455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
80465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
80475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
80485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8050c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
80515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
80535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
80555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
80565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
80585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
80605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
80615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8062868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
80635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
80645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
80665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
80675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
80685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
80695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
80712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath temp_file_path;
8072a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
80732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const uint64 kFakeSize = 100000;  // file is actually blank
80742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UploadFileElementReader::ScopedOverridingContentLengthForTests
80752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      overriding_content_length(kFakeSize);
80762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
80772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
80782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(
80797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      new UploadFileElementReader(base::MessageLoopProxy::current().get(),
80807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  temp_file_path,
80817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  0,
80827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  kuint64max,
80837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  base::Time()));
808468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
80852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
80865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
80875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
80885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/upload");
80892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.upload_data_stream = &upload_data_stream;
80905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
80915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
80935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
80948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
80955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
80975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),
80985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
80995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
81005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
81015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
81035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
81055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
81075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
81085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
81105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
81115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
81135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
81145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
81165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
81175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
81195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
81205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
81215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
81225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::DeleteFile(temp_file_path, false);
81245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
81255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
81272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath temp_file;
8128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
81292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string temp_file_content("Unreadable file.");
8130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
81312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   temp_file_content.length()));
81322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
81332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
81342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
81352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(
81367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      new UploadFileElementReader(base::MessageLoopProxy::current().get(),
81377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  temp_file,
81387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  0,
81397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  kuint64max,
81407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  base::Time()));
814168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
81422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
81435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
81445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
81455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/upload");
81462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.upload_data_stream = &upload_data_stream;
81475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
81485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If we try to upload an unreadable file, the transaction should fail.
81508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
81515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
81528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
81535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  StaticSocketDataProvider data(NULL, 0, NULL, 0);
8155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
81565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
81585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
81605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
81615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
8163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(ERR_ACCESS_DENIED, rv);
81645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
8166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(response);
81675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::DeleteFile(temp_file, false);
81695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
81705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
81724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  class FakeUploadElementReader : public UploadElementReader {
81734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   public:
81744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    FakeUploadElementReader() {}
81754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual ~FakeUploadElementReader() {}
81764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
81774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const CompletionCallback& callback() const { return callback_; }
81784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
81794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // UploadElementReader overrides:
81804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual int Init(const CompletionCallback& callback) OVERRIDE {
81814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      callback_ = callback;
81824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return ERR_IO_PENDING;
81834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
81844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual uint64 GetContentLength() const OVERRIDE { return 0; }
81854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual uint64 BytesRemaining() const OVERRIDE { return 0; }
81864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual int Read(IOBuffer* buf,
81874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                     int buf_length,
81884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                     const CompletionCallback& callback) OVERRIDE {
81894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return ERR_FAILED;
81904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
81914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
81924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   private:
81934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CompletionCallback callback_;
81944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
81954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
81964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
81974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
81984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  element_readers.push_back(fake_reader);
81994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
82004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  HttpRequestInfo request;
82024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.method = "POST";
82034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.url = GURL("http://www.google.com/upload");
82044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.upload_data_stream = &upload_data_stream;
82054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.load_flags = 0;
82064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
82084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
82098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
82104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StaticSocketDataProvider data;
82124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
82134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestCompletionCallback callback;
82154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
82164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
82174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
82184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Transaction is pending on request body initialization.
82204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_FALSE(fake_reader->callback().is_null());
82214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Return Init()'s result after the transaction gets destroyed.
82234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  trans.reset();
82244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  fake_reader->callback().Run(OK);  // Should not crash.
82254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
82264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that changes to Auth realms are treated like auth rejections.
82287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
82295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
82315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
82325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
82335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
82345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First transaction will request a resource and receive a Basic challenge
82365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // with realm="first_realm".
82375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
82385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
82395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
82405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
82415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
82425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
82445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"
82455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
82465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"),
82475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), provide an Authentication header
82505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for first_realm. The server will reject and provide a challenge with
82515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // second_realm.
82525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
82535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
82545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
82555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
82565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zmlyc3Q6YmF6\r\n"
82575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
82585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
82605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"
82615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
82625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"),
82635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This again fails, and goes back to first_realm. Make sure that the
82665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // entry is removed from cache.
82675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes3[] = {
82685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
82695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
82705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
82715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
82725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
82735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads3[] = {
82755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"
82765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
82775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"),
82785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try one last time (with the correct password) and get the resource.
82815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes4[] = {
82825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
82835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
82845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
82855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zmlyc3Q6YmFy\r\n"
82865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
82875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads4[] = {
82895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"
82905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Type: text/html; charset=iso-8859-1\r\n"
82915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 5\r\n"
82925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"
82935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "hello"),
82945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
82975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
82985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
82995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
83005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
83015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
83025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
83035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes4, arraysize(data_writes4));
8304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
8305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
8306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
8307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data4);
83085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
83105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
83125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
83138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
83145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the first request with Authorize headers. There should be a
83165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // password prompt for first_realm waiting to be filled in after the
83175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction completes.
83185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
83195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
83205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
83215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
83225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
83235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
83245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const AuthChallengeInfo* challenge = response->auth_challenge.get();
83255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(challenge == NULL);
83265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(challenge->is_proxy);
83275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
83285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("first_realm", challenge->realm);
83295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", challenge->scheme);
83305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the second request with an incorrect password. There should be a
83325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // password prompt for second_realm waiting to be filled in after the
83335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction completes.
83345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
83355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
83365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFirst, kBaz), callback2.callback());
83375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
83385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
83395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
83405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
83415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
83425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  challenge = response->auth_challenge.get();
83435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(challenge == NULL);
83445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(challenge->is_proxy);
83455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
83465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("second_realm", challenge->realm);
83475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", challenge->scheme);
83485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the third request with another incorrect password. There should be
83505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a password prompt for first_realm waiting to be filled in. If the password
83515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // prompt is not present, it indicates that the HttpAuthCacheEntry for
83525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // first_realm was not correctly removed.
83535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
83545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
83555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kSecond, kFou), callback3.callback());
83565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
83575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
83585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
83595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
83605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
83615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  challenge = response->auth_challenge.get();
83625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(challenge == NULL);
83635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(challenge->is_proxy);
83645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
83655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("first_realm", challenge->realm);
83665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", challenge->scheme);
83675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the fourth request with the correct password and username.
83695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback4;
83705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
83715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFirst, kBar), callback4.callback());
83725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
83735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback4.WaitForResult();
83745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
83755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
83765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
83775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
83785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
83795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
8381cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
8382cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
83835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
8385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
8386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
83875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
83885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8389eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
83905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
83915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
83925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
83935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
83955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
83965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
83975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
83985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
84005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
84025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
84045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
84062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
84085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
84105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
84115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair http_host_port_pair("www.google.com", 80);
8413a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  HttpServerProperties& http_server_properties =
84145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *session->http_server_properties();
84155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
84165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_server_properties.HasAlternateProtocol(http_host_port_pair));
84175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
84195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
84215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8422868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
84235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
84245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
84255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_npn_negotiated);
84265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
84285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
84295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
84305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
84325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const PortAlternateProtocolPair alternate =
84335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_server_properties.GetAlternateProtocol(http_host_port_pair);
84345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PortAlternateProtocolPair expected_alternate;
84355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_alternate.port = 443;
8436eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam());
84375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(expected_alternate.Equals(alternate));
84385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
84395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
84415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       MarkBrokenAlternateProtocolAndFallback) {
8442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
84435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
84455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
84465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
84475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
84485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
84505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
84515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
84535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
84555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
84565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
84575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
84585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
84595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
84605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
84625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
84645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8465ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
84665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
84675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Port must be < 1024, or the header will be ignored (since initial port was
84685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // port 80 (another restricted port).
84695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
84705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(request.url),
84715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      666 /* port is ignored by MockConnect anyway */,
8472eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
84735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8475868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
84765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
84775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
84795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
84805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
84815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
84835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8484868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
84855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
84865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
84885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
84895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
84905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
84925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(request.url)));
84935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const PortAlternateProtocolPair alternate =
84945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_server_properties->GetAlternateProtocol(
84955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          HostPortPair::FromURL(request.url));
84965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
84975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
84985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
85005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolPortRestrictedBlocked) {
85015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
85025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
85035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a restricted port (port < 1024).  Ensure that we can redirect in all
85045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other cases.
8505cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
85065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo restricted_port_request;
85085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.method = "GET";
85095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.url = GURL("http://www.google.com:1023/");
85105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.load_flags = 0;
85115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
85135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
85145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
85165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
85185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
85195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
85205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
85215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
85225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
85235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
85255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
85275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8528ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
85295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
85305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kUnrestrictedAlternatePort = 1024;
85315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
85325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(restricted_port_request.url),
85335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUnrestrictedAlternatePort,
8534eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
85355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8537868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
85385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
85395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(
85412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &restricted_port_request,
85422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback.callback(), BoundNetLog());
85435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
85445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invalid change to unrestricted port should fail.
85455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
85462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
85475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
85492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       AlternateProtocolPortRestrictedPermitted) {
85502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ensure that we're allowed to redirect traffic via an alternate
85512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
85522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // on a restricted port (port < 1024) if we set
85532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // enable_user_alternate_protocol_ports.
85542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8555cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
8556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.enable_user_alternate_protocol_ports = true;
85572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
85582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo restricted_port_request;
85592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  restricted_port_request.method = "GET";
85602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  restricted_port_request.url = GURL("http://www.google.com:1023/");
85612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  restricted_port_request.load_flags = 0;
85622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
85632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
85642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider first_data;
85652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  first_data.set_connect_data(mock_connect);
8566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
85672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
85682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead data_reads[] = {
85692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
85702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("hello world"),
85712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, OK),
85722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
85732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider second_data(
85742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
85762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
85782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8579ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
85802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      session->http_server_properties();
85812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kUnrestrictedAlternatePort = 1024;
85822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  http_server_properties->SetAlternateProtocol(
85832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HostPortPair::FromURL(restricted_port_request.url),
85842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kUnrestrictedAlternatePort,
8585eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
85862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
85872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8588868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
85892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
85902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
85912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, trans->Start(
85922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &restricted_port_request,
85932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback.callback(), BoundNetLog()));
85942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Change to unrestricted port should succeed.
85952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
85965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
85975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
85995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolPortRestrictedAllowed) {
86005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
86015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
86025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a restricted port (port < 1024).  Ensure that we can redirect in all
86035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other cases.
8604cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
86055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo restricted_port_request;
86075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.method = "GET";
86085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.url = GURL("http://www.google.com:1023/");
86095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.load_flags = 0;
86105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
86125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
86135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
86155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
86175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
86185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
86195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
86205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
86215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
86225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
86245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
86265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8627ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
86285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
86295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kRestrictedAlternatePort = 80;
86305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
86315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(restricted_port_request.url),
86325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kRestrictedAlternatePort,
8633eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
86345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8636868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
86375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
86385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(
86402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &restricted_port_request,
86412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback.callback(), BoundNetLog());
86425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
86435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Valid change to restricted port should pass.
86445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
86455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
86465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
86485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolPortUnrestrictedAllowed1) {
86495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
86505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
86515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a restricted port (port < 1024).  Ensure that we can redirect in all
86525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other cases.
8653cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
86545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo unrestricted_port_request;
86565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.method = "GET";
86575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.url = GURL("http://www.google.com:1024/");
86585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.load_flags = 0;
86595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
86615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
86625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
86645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
86665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
86675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
86685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
86695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
86705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
86715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
86735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
86755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8676ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
86775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
86785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kRestrictedAlternatePort = 80;
86795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
86805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(unrestricted_port_request.url),
86815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kRestrictedAlternatePort,
8682eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
86835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8685868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
86865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
86875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(
86895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &unrestricted_port_request, callback.callback(), BoundNetLog());
86905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
86915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Valid change to restricted port should pass.
86925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
86935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
86945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
86965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolPortUnrestrictedAllowed2) {
86975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
86985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
86995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a restricted port (port < 1024).  Ensure that we can redirect in all
87005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other cases.
8701cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
87025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo unrestricted_port_request;
87045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.method = "GET";
87055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.url = GURL("http://www.google.com:1024/");
87065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.load_flags = 0;
87075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
87095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
87105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
87125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
87145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
87155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
87165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
87175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
87185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
87195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
87215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
87235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8724ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
87255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
87265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kUnrestrictedAlternatePort = 1024;
87275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
87285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(unrestricted_port_request.url),
87295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUnrestrictedAlternatePort,
8730eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
87315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8733868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
87345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
87355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(
87375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &unrestricted_port_request, callback.callback(), BoundNetLog());
87385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
87395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Valid change to an unrestricted port should pass.
87405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
87415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
87425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8743cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
87445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
87455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unsafe port, and that we resume the second
87465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
8747cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
87485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
87505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
87515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
87525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
87535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The alternate protocol request will error out before we attempt to connect,
87555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so only the standard HTTP request will try to connect.
87565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
87575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
87585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
87595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
87605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
87615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(
87625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
87645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
87665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8767ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
87685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
87695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kUnsafePort = 7;
87705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
87715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(request.url),
87725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUnsafePort,
8773eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      AlternateProtocolFromNextProto(GetParam()));
87745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8776868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
87775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
87785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
87805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
87815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The HTTP request should succeed.
87825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
87835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disable alternate protocol before the asserts.
8785cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // HttpStreamFactory::set_use_alternate_protocols(false);
87865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
87885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8789868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
87905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
87915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
87935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
87945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
87955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
87965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
8798cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
8799cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
88005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
88025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
88035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
88045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
88055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8806eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
8807eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
8808eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
88095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
88105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8811eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
88125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
88135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
88145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK)
88155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
88165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
88185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
88205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
88227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
8823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
88245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
882590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
882690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
88275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
88285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
88307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
88315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
88325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
88335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data),
88345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
88355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
88365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
88385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
88395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
88405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
8841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
88425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
88445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_non_alternate_protocol_socket(
88455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
88465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_non_alternate_protocol_socket.set_connect_data(
88475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      never_finishing_connect);
8848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(
88495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &hanging_non_alternate_protocol_socket);
88505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
88525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
88542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8855868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
88565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
88585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
88595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
88605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
88625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8863868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
88645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
88655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
88675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
88685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
88695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8870868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
88715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
88735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
88745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
88755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
88775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8878868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
88795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
88805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
88815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
88825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
88845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
88855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
88865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
8888cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
8889cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
88905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
88925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
88935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
88945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
88955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8896eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
8897eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
8898eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
88995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
89005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8901eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
89025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
89035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
89045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
89055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
89065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
89085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
89095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
8910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
89115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
89135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_socket(
89145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
89155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_socket.set_connect_data(never_finishing_connect);
89165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket 2 and 3 are the hanging Alternate-Protocol and
89175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // non-Alternate-Protocol jobs from the 2nd transaction.
8918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
89205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
89227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
8923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
89245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
892590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(
892690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
892790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
892890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
89295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
89305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req1),
89315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2),
89325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
89337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
89347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
89357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
89367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
89375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
89385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp1),
89395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data1),
89405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2),
89415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data2),
89425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
89435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
89445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
89465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      2,  // wait for writes to finish before reading.
89475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
89485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
89495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket 4 is the successful Alternate-Protocol for transaction 3.
8950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
89515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
8953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
89545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
89565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
8957868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
89585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
89605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
89615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
89625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans1.GetResponseInfo();
89645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8965868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
89665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
89675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
89695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
89705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
89715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
8973868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
89745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
89755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
89765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
8978868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
89795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
89805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
89815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
89835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback3.WaitForResult());
89845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans2.GetResponseInfo();
89865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8987868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
89885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
89895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
89905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
89915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
89925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
89935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans3.GetResponseInfo();
89955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8996868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
89975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
89985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
89995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
90005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
90015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
90025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
90035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
9005cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
9006cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
90075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
90095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
90105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
90115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
90125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9013eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
9014eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
9015eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
90165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
90175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
9018eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
90195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
90205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
90215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
90225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
90235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
90255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
9026c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
90275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
90297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
9030c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
90315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
90335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_alternate_protocol_socket(
90345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
90355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_alternate_protocol_socket.set_connect_data(
90365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      never_finishing_connect);
9037c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(
90385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &hanging_alternate_protocol_socket);
90395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2nd request is just a copy of the first one, over HTTP again.
9041c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
90425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
90445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9045c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
90462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9047868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
90485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
90505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
90515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
90525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
90545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9055868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
90565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
90575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
90595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
90605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
90615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9062868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
90635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
90655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
90665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
90675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
90695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9070868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
90715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
90725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
90735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_npn_negotiated);
90745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
90765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
90775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
90785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CapturingProxyResolver : public ProxyResolver {
90805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
90815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
90825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~CapturingProxyResolver() {}
90835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetProxyForURL(const GURL& url,
90855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ProxyInfo* results,
90865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const CompletionCallback& callback,
90875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             RequestHandle* request,
90882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const BoundNetLog& net_log) OVERRIDE {
90895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
90905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             HostPortPair("myproxy", 80));
90915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    results->UseProxyServer(proxy_server);
90925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resolved_.push_back(url);
90935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
90945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
90955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void CancelRequest(RequestHandle request) OVERRIDE {
90975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
90985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
90995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
91015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
91025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return LOAD_STATE_IDLE;
91035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
91045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void CancelSetPacScript() OVERRIDE {
91065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
91075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
91085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
91102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const CompletionCallback& /*callback*/) OVERRIDE {
91115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
91125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
91135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::vector<GURL>& resolved() const { return resolved_; }
91155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
91175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<GURL> resolved_;
91185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
91205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
91215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
91235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       UseAlternateProtocolForTunneledNpnSpdy) {
9124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
9125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
91265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig proxy_config;
91285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxy_config.set_auto_detect(true);
91295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxy_config.set_pac_url(GURL("http://fooproxyurl"));
91305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingProxyResolver* capturing_proxy_resolver =
91325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new CapturingProxyResolver();
9133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(new ProxyService(
91345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
91355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL));
91362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
9137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
91385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
91405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
91415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
91425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
91435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
9145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
9146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
91475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
91485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
9149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
91505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
91515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
91525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
91535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
91545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
91565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
9157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
91585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
91607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
9161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
91625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
916390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
916490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
91655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
91665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
91675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
91685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),  // 0
916990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CreateMockWrite(*req),                              // 3
91705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
91715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
91735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
91757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
91765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
91775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1),  // 1
91785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp.get(), 4),  // 2, 4
91795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data.get(), 4),  // 5
91805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0, 4),  // 6
91815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
91825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
91845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
91855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
9186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
91875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
91895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_non_alternate_protocol_socket(
91905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
91915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_non_alternate_protocol_socket.set_connect_data(
91925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      never_finishing_connect);
9193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(
91945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &hanging_non_alternate_protocol_socket);
91955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
91975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
91992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
92015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
92035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
92045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
92055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
92075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
92095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
92105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
92115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_npn_negotiated);
92125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
92145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
92155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
92165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
92185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
92205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
92215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
92225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
92245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
92265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
92275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
92285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
92295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
92315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
92325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
92335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://www.google.com/",
92345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            capturing_proxy_resolver->resolved()[0].spec());
92355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("https://www.google.com/",
92365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            capturing_proxy_resolver->resolved()[1].spec());
92375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
92392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
92402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
92412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
92425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
92435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
92455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
9246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
9247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
92485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
92505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
92515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
92525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
92535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
9255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
9256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
92575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
92585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
9259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
92605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
92615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
92625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
92635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
92655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
9266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
92675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
92697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
9270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
92715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
927290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
927390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
92745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
92755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
92777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
92785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
92795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
92805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data),
92815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
92825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
92835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
92855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
92865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
92875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
9288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
92895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
92915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
92935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
92965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
92985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
92995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
93005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
93025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
93045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
93055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
93075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
93085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
93095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up an initial SpdySession in the pool to reuse.
93115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair host_port_pair("www.google.com", 443);
931290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
9313e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                     PRIVACY_MODE_DISABLED);
9314ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<SpdySession> spdy_session =
93157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      CreateSecureSpdySession(session, key, BoundNetLog());
93165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9317868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
93185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
93205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
93215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
93225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
93245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
93265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
93275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
93285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
93295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
93315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
93325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
93335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GenerateAuthToken is a mighty big test.
93355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It tests all permutation of GenerateAuthToken behavior:
93365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - Synchronous and Asynchronous completion.
93375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - OK or error on completion.
93385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - Direct connection, non-authenticating proxy, and authenticating proxy.
93395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - HTTP or HTTPS backend (to include proxy tunneling).
93405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - Non-authenticating and authenticating backend.
93415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
93425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In all, there are 44 reasonable permuations (for example, if there are
93435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// problems generating an auth token for an authenticating proxy, we don't
93445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// need to test all permutations of the backend server).
93455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
93465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The test proceeds by going over each of the configuration cases, and
93475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// potentially running up to three rounds in each of the tests. The TestConfig
93485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specifies both the configuration for the test as well as the expectations
93495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for the results.
93507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
93515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kServer[] = "http://www.example.com";
93525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kSecureServer[] = "https://www.example.com";
93535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kProxy[] = "myproxy:70";
93545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
93555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum AuthTiming {
93575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AUTH_NONE,
93585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AUTH_SYNC,
93595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AUTH_ASYNC,
93605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
93615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGet(
93635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET / HTTP/1.1\r\n"
93645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
93655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Connection: keep-alive\r\n\r\n");
93665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetProxy(
93675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET http://www.example.com/ HTTP/1.1\r\n"
93685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
93695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n\r\n");
93705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetAuth(
93715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET / HTTP/1.1\r\n"
93725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
93735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Connection: keep-alive\r\n"
93745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Authorization: auth_token\r\n\r\n");
93755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetProxyAuth(
93765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET http://www.example.com/ HTTP/1.1\r\n"
93775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
93785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n"
93795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Authorization: auth_token\r\n\r\n");
93805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetAuthThroughProxy(
93815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET http://www.example.com/ HTTP/1.1\r\n"
93825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
93835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n"
93845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Authorization: auth_token\r\n\r\n");
93855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetAuthWithProxyAuth(
93865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET http://www.example.com/ HTTP/1.1\r\n"
93875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
93885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n"
93895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Authorization: auth_token\r\n"
93905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Authorization: auth_token\r\n\r\n");
93915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kConnect(
93925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "CONNECT www.example.com:443 HTTP/1.1\r\n"
93935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
93945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n\r\n");
93955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kConnectProxyAuth(
93965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "CONNECT www.example.com:443 HTTP/1.1\r\n"
93975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
93985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n"
93995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Authorization: auth_token\r\n\r\n");
94005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kSuccess(
94025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\r\n"
94035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
94045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 3\r\n\r\n"
94055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Yes");
94065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kFailure(
94075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Should not be called.");
94085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kServerChallenge(
94095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 401 Unauthorized\r\n"
94105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "WWW-Authenticate: Mock realm=server\r\n"
94115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
94125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 14\r\n\r\n"
94135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Unauthorized\r\n");
94145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kProxyChallenge(
94155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 407 Unauthorized\r\n"
94165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Authenticate: Mock realm=proxy\r\n"
94175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: close\r\n"
94185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
94195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 14\r\n\r\n"
94205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Unauthorized\r\n");
94215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kProxyConnected(
94225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 Connection Established\r\n\r\n");
94235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
94255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // no constructors, but the C++ compiler on Windows warns about
94265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // unspecified data in compound literals. So, moved to using constructors,
94275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and TestRound's created with the default constructor should not be used.
94285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct TestRound {
94295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRound()
94305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : expected_rv(ERR_UNEXPECTED),
94315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_write(NULL),
94325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_read(NULL) {
94335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
94345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRound(const MockWrite& write_arg, const MockRead& read_arg,
94355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              int expected_rv_arg)
94365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : write(write_arg),
94375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          read(read_arg),
94385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          expected_rv(expected_rv_arg),
94395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_write(NULL),
94405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_read(NULL) {
94415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
94425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRound(const MockWrite& write_arg, const MockRead& read_arg,
94435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              int expected_rv_arg, const MockWrite* extra_write_arg,
94445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              const MockRead* extra_read_arg)
94455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : write(write_arg),
94465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          read(read_arg),
94475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          expected_rv(expected_rv_arg),
94485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_write(extra_write_arg),
94495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_read(extra_read_arg) {
94505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
94515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite write;
94525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead read;
94535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int expected_rv;
94545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockWrite* extra_write;
94555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockRead* extra_read;
94565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
94575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kNoSSL = 500;
94595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct TestConfig {
94615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* proxy_url;
94625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AuthTiming proxy_auth_timing;
94635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int proxy_auth_rv;
94645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* server_url;
94655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AuthTiming server_auth_timing;
94665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int server_auth_rv;
94675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int num_auth_rounds;
94685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int first_ssl_round;
94695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRound rounds[3];
94705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } test_configs[] = {
94715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTP server with a direct connection.
94725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
94735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kSuccess, OK)}},
94745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTP server with a direct connection.
94755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
94765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
94775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
94785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
94795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
94805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
94815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
94825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
94835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
94845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
94855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
94865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
94875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTP server through a non-authenticating proxy.
94885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
94895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kSuccess, OK)}},
94905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTP server through a non-authenticating proxy.
94915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
94925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kServerChallenge, OK),
94935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
94945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
94955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kServerChallenge, OK),
94965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
94975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
94985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kServerChallenge, OK),
94995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
95005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
95015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kServerChallenge, OK),
95025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
95035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTP server through an authenticating proxy.
95045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
95055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kSuccess, OK)}},
95075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
95085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
95105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
95115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kSuccess, OK)}},
95135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
95145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
95165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTP server through an authenticating proxy.
95175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
95185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
95215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
95225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
95255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
95265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
95295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
95305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
95335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
95345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
95375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
95385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
95415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
95425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
95455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
95465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
95495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTPS server with a direct connection.
95505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
95515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kSuccess, OK)}},
95525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTPS server with a direct connection.
95535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
95545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
95555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
95565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
95575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
95585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
95595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
95605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
95615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
95625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
95635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
95645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
95655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTPS server with a non-authenticating proxy.
95665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
95675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
95685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTPS server through a non-authenticating proxy.
95695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
95705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
95715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
95725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
95735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
95745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
95755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
95765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
95775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
95785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
95795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
95805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
95815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-Authenticating HTTPS server through an authenticating proxy.
95825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
95835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
95845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
95855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
95865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
95875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
95885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
95895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
95905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
95915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
95925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
95935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
95945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTPS server through an authenticating proxy.
95955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
95965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
95975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
95985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
95995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
96005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
96015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
96035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
96045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
96055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
96065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
96085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
96095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
96105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
96115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
96135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
96145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
96155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
96165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
96185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
96195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
96205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
96215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
96235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
96245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
96255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
96265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
96285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
96295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
96305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
96315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
96335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
96345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
96355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
96365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
96385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpAuthHandlerMock::Factory* auth_factory(
96395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new HttpAuthHandlerMock::Factory());
9640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.http_auth_handler_factory.reset(auth_factory);
96415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const TestConfig& test_config = test_configs[i];
96425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Set up authentication handlers as necessary.
96445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_config.proxy_auth_timing != AUTH_NONE) {
96455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (int n = 0; n < 2; n++) {
96465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
96475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::string auth_challenge = "Mock realm=proxy";
96485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL origin(test_config.proxy_url);
9649a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9650a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             auth_challenge.end());
96515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
96525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        origin, BoundNetLog());
96535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        auth_handler->SetGenerateExpectation(
96545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            test_config.proxy_auth_timing == AUTH_ASYNC,
96555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            test_config.proxy_auth_rv);
96565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
96575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
96585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
96595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_config.server_auth_timing != AUTH_NONE) {
96605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
96615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string auth_challenge = "Mock realm=server";
96625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL origin(test_config.server_url);
9663a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9664a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                           auth_challenge.end());
96655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
96665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      origin, BoundNetLog());
96675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      auth_handler->SetGenerateExpectation(
96685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          test_config.server_auth_timing == AUTH_ASYNC,
96695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          test_config.server_auth_rv);
96705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
96715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
96725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_config.proxy_url) {
9673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.proxy_service.reset(
96745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ProxyService::CreateFixed(test_config.proxy_url));
96755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
9676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.proxy_service.reset(ProxyService::CreateDirect());
96775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
96785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
96805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
96815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL(test_config.server_url);
96825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
96835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
96858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
96865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int round = 0; round < test_config.num_auth_rounds; ++round) {
96885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const TestRound& read_write_round = test_config.rounds[round];
96895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Set up expected reads and writes.
96915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead reads[2];
96925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reads[0] = read_write_round.read;
96935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t length_reads = 1;
96945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (read_write_round.extra_read) {
96955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reads[1] = *read_write_round.extra_read;
96965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        length_reads = 2;
96975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
96985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite writes[2];
97005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writes[0] = read_write_round.write;
97015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t length_writes = 1;
97025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (read_write_round.extra_write) {
97035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        writes[1] = *read_write_round.extra_write;
97045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        length_writes = 2;
97055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
97065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      StaticSocketDataProvider data_provider(
97075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          reads, length_reads, writes, length_writes);
9708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
97095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Add an SSL sequence if necessary.
97115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
97125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (round >= test_config.first_ssl_round)
9713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        session_deps_.socket_factory->AddSSLSocketDataProvider(
97145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &ssl_socket_data_provider);
97155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Start or restart the transaction.
97175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestCompletionCallback callback;
97185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int rv;
97195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (round == 0) {
97205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = trans.Start(&request, callback.callback(), BoundNetLog());
97215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
97225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = trans.RestartWithAuth(
97235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            AuthCredentials(kFoo, kBar), callback.callback());
97245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
97255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (rv == ERR_IO_PENDING)
97265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = callback.WaitForResult();
97275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Compare results with expected data.
97295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(read_write_round.expected_rv, rv);
97305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const HttpResponseInfo* response = trans.GetResponseInfo();
97315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (read_write_round.expected_rv == OK) {
97325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ASSERT_TRUE(response != NULL);
97335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
97345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(response == NULL);
97355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_EQ(round + 1, test_config.num_auth_rounds);
97365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
97375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
97385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (round + 1 < test_config.num_auth_rounds) {
97395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_FALSE(response->auth_challenge.get() == NULL);
97405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
97415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(response->auth_challenge.get() == NULL);
97425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
97435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
97445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
97455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
97465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
97485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do multi-round authentication and make sure it works correctly.
97495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerMock::Factory* auth_factory(
97505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new HttpAuthHandlerMock::Factory());
9751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.http_auth_handler_factory.reset(auth_factory);
9752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->set_synchronous_mode(true);
97555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
97575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->set_connection_based(true);
97585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string auth_challenge = "Mock realm=server";
97595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL origin("http://www.example.com");
9760a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9761a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                       auth_challenge.end());
97625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
97635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  origin, BoundNetLog());
97645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
97655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = OK;
97675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = NULL;
97685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
97695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
97705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = origin;
97715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
97725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
97745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use a TCP Socket Pool with only one connection per group. This is used
97765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to validate that the TCP socket is not released to the pool between
97775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // each round of multi-round authentication.
97785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpNetworkSessionPeer session_peer(session);
97795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
97805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
97815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50,  // Max sockets for pool
97825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,   // Max sockets per group
97835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &transport_pool_histograms,
9784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.host_resolver.get(),
9785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.socket_factory.get(),
9786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.net_log);
9787f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
9788f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new MockClientSocketPoolManager);
97895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_pool_manager->SetTransportSocketPool(transport_pool);
9790f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  session_peer.SetClientSocketPoolManager(
9791f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      mock_pool_manager.PassAs<ClientSocketPoolManager>());
97925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9794868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
97955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
97965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGet(
97985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET / HTTP/1.1\r\n"
97995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
98005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Connection: keep-alive\r\n\r\n");
98015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetAuth(
98025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET / HTTP/1.1\r\n"
98035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
98045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Connection: keep-alive\r\n"
98055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Authorization: auth_token\r\n\r\n");
98065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kServerChallenge(
98085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 401 Unauthorized\r\n"
98095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "WWW-Authenticate: Mock realm=server\r\n"
98105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
98115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 14\r\n\r\n"
98125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Unauthorized\r\n");
98135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kSuccess(
98145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\r\n"
98155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
98165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 3\r\n\r\n"
98175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Yes");
98185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
98205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First round
98215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGet,
98225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Second round
98235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGetAuth,
98245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Third round
98255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGetAuth,
98265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fourth round
98275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGetAuth,
98285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Competing request
98295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGet,
98305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
98315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
98325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First round
98335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kServerChallenge,
98345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Second round
98355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kServerChallenge,
98365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Third round
98375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kServerChallenge,
98385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fourth round
98395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kSuccess,
98405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Competing response
98415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kSuccess,
98425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
98435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data_provider(reads, arraysize(reads),
98445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         writes, arraysize(writes));
9845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
98465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kSocketGroup = "www.example.com:80";
98485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First round of authentication.
98505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->SetGenerateExpectation(false, OK);
98515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
98525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
98535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
98545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
98555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
98565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
98575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->auth_challenge.get() == NULL);
98585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
98595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In between rounds, another request comes in for the same domain.
98615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It should not be able to grab the TCP socket that trans has already
98625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // claimed.
98635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans_compete(
9864868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
98655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_compete;
98665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans_compete->Start(
98675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &request, callback_compete.callback(), BoundNetLog());
98685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
98695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // callback_compete.WaitForResult at this point would stall forever,
98705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since the HttpNetworkTransaction does not release the request back to
98715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the pool until after authentication completes.
98725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second round of authentication.
98745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->SetGenerateExpectation(false, OK);
98755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
98765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
98775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
98785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
98795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
98805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
98815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
98825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
98835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Third round of authentication.
98855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->SetGenerateExpectation(false, OK);
98865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
98875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
98885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
98895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
98905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
98915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
98925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
98935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
98945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fourth round of authentication, which completes successfully.
98965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->SetGenerateExpectation(false, OK);
98975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
98985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
98995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
99005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
99015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
99025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
99035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
99045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
99055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read the body since the fourth round was successful. This will also
99075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // release the socket back to the pool.
99085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
9909868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
99105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
99115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
99125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, rv);
9913868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
99145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, rv);
99155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There are still 0 idle sockets, since the trans_compete transaction
99165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will be handed it immediately after trans releases it to the group.
99175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
99185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The competing request can now finish. Wait for the headers and then
99205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // read the body.
99215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback_compete.WaitForResult();
99225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
9923868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
99245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
99255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
99265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, rv);
9927868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
99285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, rv);
99295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finally, the socket is released to the group.
99315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
99325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
99335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This tests the case that a request is issued via http instead of spdy after
99355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// npn is negotiated.
99367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
9937cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
9938cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NextProtoVector next_protos;
9939ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  next_protos.push_back(kProtoHTTP11);
9940cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = next_protos;
9941cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
99425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
99435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
99445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
99455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
99465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
99485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
99495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
99505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
99515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
99525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9953eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
9954eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
9955eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
99565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
99575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
9958eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
99595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
99605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
99615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
99625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
99645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
99655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl.next_proto = "http/1.1";
99665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl.protocol_negotiated = kProtoHTTP11;
99675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
99695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
99715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
9972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
99735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
99755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
99772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9978868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
99795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
99815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
99835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
99845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
99865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9987868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
99885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
99895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
99915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
99925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
99935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
99955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
99965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
99975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
99995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate the SSL handshake completing with an NPN negotiation
100005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // followed by an immediate server closing of the socket.
100015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fix crash:  http://crbug.com/46369
10002cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
10003cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
100045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
100065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
100075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
100085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
100095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
100117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
10012c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
100135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1001490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
1001590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
100165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
100175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
100195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, 0, 0)   // Not async - return 0 immediately.
100205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
100215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
100235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,  // don't wait in this case, immediate hangup.
100245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
100255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
10026c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
100275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
100295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10030c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
100312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10032868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
100335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
100355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
100365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
100375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
100385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10039ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// A subclass of HttpAuthHandlerMock that records the request URL when
10040ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// it gets it. This is needed since the auth handler may get destroyed
10041ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// before we get a chance to query it.
10042ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10043ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch public:
10044ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10045ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
10046ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual ~UrlRecordingHttpAuthHandlerMock() {}
10047ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
10048ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch protected:
10049ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10050ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                    const HttpRequestInfo* request,
10051ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                    const CompletionCallback& callback,
10052ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                    std::string* auth_token) OVERRIDE {
10053ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    *url_ = request->url;
10054ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10055ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        credentials, request, callback, auth_token);
10056ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
10057ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
10058ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch private:
10059ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  GURL* url_;
10060ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch};
10061ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
100627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
100635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This test ensures that the URL passed into the proxy is upgraded
100645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to https when doing an Alternate Protocol upgrade.
10065cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
10066cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
100675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10068c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
100692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
100702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
10071c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
10072ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  GURL request_url;
10073ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  {
10074ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    HttpAuthHandlerMock::Factory* auth_factory =
10075ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        new HttpAuthHandlerMock::Factory();
10076ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    UrlRecordingHttpAuthHandlerMock* auth_handler =
10077ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        new UrlRecordingHttpAuthHandlerMock(&request_url);
10078ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10079ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    auth_factory->set_do_init_from_challenge(true);
10080ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    session_deps_.http_auth_handler_factory.reset(auth_factory);
10081ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
100825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
100845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
100855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com");
100865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
100875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First round goes unauthenticated through the proxy.
100895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes_1[] = {
100905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
100915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
100925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
100935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
100945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
100955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads_1[] = {
100965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
100975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"
100985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Alternate-Protocol: 443:npn-spdy/2\r\n"
100995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Proxy-Connection: close\r\n"
101005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"),
101015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
101025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
101035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  data_writes_1, arraysize(data_writes_1));
101045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second round tries to tunnel to www.google.com due to the
101065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Alternate-Protocol announcement in the first round. It fails due
101075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to a proxy authentication challenge.
101085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the failure, a tunnel is established to www.google.com using
101095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Proxy-Authorization headers. There is then a SPDY request round.
101105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
101115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: Despite the "Proxy-Connection: Close", these are done on the
101125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
101135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // does a Disconnect and Connect on the same socket, rather than trying
101145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to obtain a new one.
101155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
101165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: Originally, the proxy response to the second CONNECT request
101175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // simply returned another 407 so the unit test could skip the SSL connection
101185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // establishment and SPDY framing issues. Alas, the
101195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // retry-http-when-alternate-protocol fails logic kicks in, which was more
101205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // complicated to set up expectations for than the SPDY session.
101215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1012290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
1012390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
101247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
101257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
101265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes_2[] = {
101285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First connection attempt without Proxy-Authorization.
101295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
101305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
101315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
101325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
101335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Second connection attempt with Proxy-Authorization.
101355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
101365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
101375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
101385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: auth_token\r\n"
101395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
101405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SPDY request
101425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req),
101435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
101445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
101455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         "Proxy-Authenticate: Mock\r\n"
101465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         "Proxy-Connection: close\r\n"
101475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         "\r\n");
101485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
101495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads_2[] = {
101505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First connection attempt fails
101515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
101525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kRejectConnectResponse,
101535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(kRejectConnectResponse) - 1, 1),
101545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Second connection attempt passes
101565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kAcceptConnectResponse,
101575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(kAcceptConnectResponse) -1, 4),
101585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SPDY response
101605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp.get(), 6),
101615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data.get(), 6),
101625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0, 6),
101635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
101645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data_2(
101655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads_2, arraysize(data_reads_2),
101665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_writes_2, arraysize(data_writes_2));
101675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
101697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
101705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
101725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_non_alternate_protocol_socket(
101735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
101745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_non_alternate_protocol_socket.set_connect_data(
101755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      never_finishing_connect);
101765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(
101815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &hanging_non_alternate_protocol_socket);
10182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
101835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First round should work and provide the Alternate-Protocol state.
101855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_1;
101862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans_1(
10187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
101885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
101895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
101905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback_1.WaitForResult());
101915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second round should attempt a tunnel connect and get an auth challenge.
101935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_2;
101942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans_2(
10195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
101965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
101975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
101985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback_2.WaitForResult());
101995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans_2->GetResponseInfo();
102005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
102015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(response->auth_challenge.get() == NULL);
102025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restart with auth. Tunnel should work and response received.
102045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_3;
102055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans_2->RestartWithAuth(
102065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback_3.callback());
102075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
102085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback_3.WaitForResult());
102095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After all that work, these two lines (or actually, just the scheme) are
102115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // what this test is all about. Make sure it happens correctly.
102125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("https", request_url.scheme());
102135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com", request_url.host());
102145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
102162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
102172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
102182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
102195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
102205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that if we cancel the transaction as the connection is completing, that
102225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// everything tears down correctly.
102237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
102245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setup everything about the connection to complete synchronously, so that
102255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // after calling HttpNetworkTransaction::Start, the only thing we're waiting
102265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for is the callback from the HttpStreamRequest.
102275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Then cancel the transaction.
102285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that we don't crash.
102295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(SYNCHRONOUS, OK);
102305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
102315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
102325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, "hello world"),
102335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
102345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
102355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
102375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
102385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
102395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
102405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->set_synchronous_mode(true);
102428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
102435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
102448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
102455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
102475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.set_connect_data(mock_connect);
10248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
102495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
102515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
102535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), log.bound());
102545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
102555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();  // Cancel the transaction here.
102565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
102585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
102595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Test that if a transaction is cancelled after receiving the headers, the
10261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// stream is drained properly and added back to the socket pool.  The main
10262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// purpose of this test is to make sure that an HttpStreamParser can be read
10263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// from after the HttpNetworkTransaction and the objects it owns have been
10264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// deleted.
10265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// See http://crbug.com/368418
10266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
10267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MockRead data_reads[] = {
10268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
10269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockRead(ASYNC, "Content-Length: 2\r\n"),
10270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
10271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockRead(ASYNC, "1"),
10272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // 2 async reads are necessary to trigger a ReadResponseBody call after the
10273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // HttpNetworkTransaction has been deleted.
10274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockRead(ASYNC, "2"),
10275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_IO_PENDING),  // Should never read this.
10276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  };
10277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
10279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  {
10283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    HttpRequestInfo request;
10284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    request.method = "GET";
10285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    request.url = GURL("http://www.google.com/");
10286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    request.load_flags = 0;
10287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
10289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    TestCompletionCallback callback;
10290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int rv = trans.Start(&request, callback.callback(), BoundNetLog());
10292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
10293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    callback.WaitForResult();
10294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const HttpResponseInfo* response = trans.GetResponseInfo();
10296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
10297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_TRUE(response->headers.get() != NULL);
10298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // The transaction and HttpRequestInfo are deleted.
10301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
10302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Let the HttpResponseBodyDrainer drain the socket.
10304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
10305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Socket should now be idle, waiting to be reused.
10307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
10308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
10309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
103105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a basic GET request through a proxy.
103117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ProxyGet) {
10312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
103132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
103145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
10315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
10316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
103175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
103195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
103205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
103215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
103235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
103245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
103255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
103265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
103275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
103295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
103305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
103315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
103325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
103335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
103345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
103365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
10337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
103385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
103405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
103435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
103455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
103465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
103485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
103495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
103515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
103525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
103545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
103555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
103565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_proxy);
10357f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(
10358f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
103595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
103602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
103612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
103622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
103632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
103642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
103655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
103665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a basic HTTPS GET request through a proxy.
103687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
10369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
103702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
103715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
10372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
10373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
103745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
103765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
103775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
103785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
103805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
103815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
103825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
103835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
103845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
103865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
103875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
103885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
103895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
103915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
103925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
103945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
103955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
103965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
103975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
103985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
104005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
10401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
104025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
10403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
104045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
104065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10408868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
104095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
104115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
104125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
104145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
104155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
104165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
104175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
104185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
104195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
104205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
104215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
104225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
104235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
104245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
104265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
104275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
104295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
104305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
104315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
104325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_proxy);
10433f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(
10434f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
104352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
104362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
104372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
104382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
104392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
104405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
104415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a basic HTTPS GET request through a proxy, but the server hangs up
104435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// while establishing the tunnel.
104447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
10445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
104465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
10447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
10448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
104495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
104515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
104525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
104535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
104555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
104565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
104575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
104585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
104595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
104615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
104625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
104635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
104645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
104665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
104675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
104685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),  // EOF
104695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
104705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
104725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
10473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
104745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
10475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
104765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
104785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10480868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
104815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
104835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
104845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
104865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
104875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
104885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
104895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
104905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
104915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
104925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
104935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
104945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
104955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
104965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
104975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test for crbug.com/55424.
104997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
1050090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
1050190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
105025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
105035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
105057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
105065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
105075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
105085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data),
105095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
105105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
105115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
105135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
105145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
105155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
10516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
105175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
105197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
10520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
105215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
105235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up an initial SpdySession in the pool to reuse.
105255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair host_port_pair("www.google.com", 443);
1052690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
10527e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                     PRIVACY_MODE_DISABLED);
10528ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<SpdySession> spdy_session =
105297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      CreateInsecureSpdySession(session, key, BoundNetLog());
105305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
105325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
105335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
105345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
105355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is the important line that marks this as a preconnect.
105375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
105385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
105415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestCompletionCallback callback;
105435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
105445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
105455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
105465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
105475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Given a net error, cause that error to be returned from the first Write()
105495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// call and verify that the HttpTransaction fails with that error.
105507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
10551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int error, IoMode mode) {
105525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestInfo request_info;
105535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.url = GURL("https://www.example.com/");
105545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.method = "GET";
105555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.load_flags = net::LOAD_NORMAL;
105565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data(mode, OK);
105585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::MockWrite data_writes[] = {
105595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::MockWrite(mode, error),
105605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
105615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data(NULL, 0,
105625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     data_writes, arraysize(data_writes));
10563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
10564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
105655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
105672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10568868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
105695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
105715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
105725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == net::ERR_IO_PENDING)
105735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
105745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(error, rv);
105755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
105765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
105785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Just check a grab bag of cert errors.
105795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kErrors[] = {
105805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ERR_CERT_COMMON_NAME_INVALID,
105815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ERR_CERT_AUTHORITY_INVALID,
105825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ERR_CERT_DATE_INVALID,
105835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
105845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kErrors); i++) {
105855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckErrorIsPassedBack(kErrors[i], ASYNC);
105865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
105875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
105885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
105895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure that a client certificate is removed from the SSL client auth
105915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cache when:
105925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  1) No proxy is involved.
105935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  2) TLS False Start is disabled.
105945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  3) The initial TLS handshake requests a client certificate.
105955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  4) The client supplies an invalid/unacceptable certificate.
105967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
105975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ClientAuthCertCache_Direct_NoFalseStart) {
105985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestInfo request_info;
105995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.url = GURL("https://www.example.com/");
106005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.method = "GET";
106015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.load_flags = net::LOAD_NORMAL;
106025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
106045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cert_request->host_and_port = HostPortPair("www.example.com", 443);
106055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data1 contains the data for the first SSL handshake. When a
106075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CertificateRequest is received for the first time, the handshake will
106085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be aborted to allow the caller to provide a certificate.
106095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
106105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data1.cert_request_info = cert_request.get();
10611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
106125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
106145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data2 contains the data for the second SSL handshake. When TLS
106165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // False Start is not being used, the result of the SSL handshake will be
106175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // returned as part of the SSLClientSocket::Connect() call. This test
106185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // matches the result of a server sending a handshake_failure alert,
106195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // rather than a Finished message, because it requires a client
106205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate and none was supplied.
106215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
106225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data2.cert_request_info = cert_request.get();
10623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
106245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
10625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
106265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data3 contains the data for the third SSL handshake. When a
106285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection to a server fails during an SSL handshake,
106295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
106305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection was attempted with TLSv1.1. This is transparent to the caller
106315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the HttpNetworkTransaction. Because this test failure is due to
106325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // requiring a client certificate, this fallback handshake should also
106335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fail.
106345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
106355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data3.cert_request_info = cert_request.get();
10636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
106375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
10638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
106395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data4 contains the data for the fourth SSL handshake. When a
106415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection to a server fails during an SSL handshake,
106425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
106435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection was attempted with TLSv1. This is transparent to the caller
106445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the HttpNetworkTransaction. Because this test failure is due to
106455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // requiring a client certificate, this fallback handshake should also
106465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fail.
106475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
106485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data4.cert_request_info = cert_request.get();
10649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
106505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
10651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data4);
106525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10653868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Need one more if TLSv1.2 is enabled.
10654868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10655868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ssl_data5.cert_request_info = cert_request.get();
10656868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10657868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10658868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data5);
10659868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
106612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10662868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
106635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Begin the SSL handshake with the peer. This consumes ssl_data1.
106655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
106665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
106675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_IO_PENDING, rv);
106685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the SSL handshake, which should abort due to requiring a
106705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // client certificate.
106715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
106725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
106735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Indicate that no certificate should be supplied. From the perspective
106755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of SSLClientCertCache, NULL is just as meaningful as a real
106765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate, so this is the same as supply a
106775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // legitimate-but-unacceptable certificate.
106785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithCertificate(NULL, callback.callback());
106795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_IO_PENDING, rv);
106805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure the certificate was added to the client auth cache before
106825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // allowing the connection to continue restarting.
106835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> client_cert;
106845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
106855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      HostPortPair("www.example.com", 443), &client_cert));
106865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(NULL, client_cert.get());
106875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restart the handshake. This will consume ssl_data2, which fails, and
106895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // then consume ssl_data3 and ssl_data4, both of which should also fail.
106905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The result code is checked against what ssl_data4 should return.
106915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
106925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
106935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that the client certificate is removed from the cache on a
106955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // handshake failure.
106965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
106975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      HostPortPair("www.example.com", 443), &client_cert));
106985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
106995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure that a client certificate is removed from the SSL client auth
107015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cache when:
107025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  1) No proxy is involved.
107035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  2) TLS False Start is enabled.
107045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  3) The initial TLS handshake requests a client certificate.
107055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  4) The client supplies an invalid/unacceptable certificate.
107067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
107075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ClientAuthCertCache_Direct_FalseStart) {
107085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestInfo request_info;
107095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.url = GURL("https://www.example.com/");
107105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.method = "GET";
107115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.load_flags = net::LOAD_NORMAL;
107125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
107145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cert_request->host_and_port = HostPortPair("www.example.com", 443);
107155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When TLS False Start is used, SSLClientSocket::Connect() calls will
107175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // return successfully after reading up to the peer's Certificate message.
107185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is to allow the caller to call SSLClientSocket::Write(), which can
107195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // enqueue application data to be sent in the same packet as the
107205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ChangeCipherSpec and Finished messages.
107215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The actual handshake will be finished when SSLClientSocket::Read() is
107225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called, which expects to process the peer's ChangeCipherSpec and
107235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finished messages. If there was an error negotiating with the peer,
107245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // such as due to the peer requiring a client certificate when none was
107255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // supplied, the alert sent by the peer won't be processed until Read() is
107265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called.
107275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Like the non-False Start case, when a client certificate is requested by
107295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the peer, the handshake is aborted during the Connect() call.
107305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data1 represents the initial SSL handshake with the peer.
107315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
107325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data1.cert_request_info = cert_request.get();
10733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
107345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
107365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When a client certificate is supplied, Connect() will not be aborted
107385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the peer requests the certificate. Instead, the handshake will
107395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // artificially succeed, allowing the caller to write the HTTP request to
107405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the socket. The handshake messages are not processed until Read() is
107415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called, which then detects that the handshake was aborted, due to the
107425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // peer sending a handshake_failure because it requires a client
107435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate.
107445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
107455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data2.cert_request_info = cert_request.get();
10746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
107475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::MockRead data2_reads[] = {
107485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
107495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
107505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data2(
107515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data2_reads, arraysize(data2_reads), NULL, 0);
10752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
107535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
107555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the data for the SSL handshake once the TLSv1.1 connection falls back to
107565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TLSv1. It has the same behaviour as [ssl_]data2.
107575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
107585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data3.cert_request_info = cert_request.get();
10759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
107605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data3(
107615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data2_reads, arraysize(data2_reads), NULL, 0);
10762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
107635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
107655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
107665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
107675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data4.cert_request_info = cert_request.get();
10768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
107695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data4(
107705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data2_reads, arraysize(data2_reads), NULL, 0);
10771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data4);
107725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10773868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Need one more if TLSv1.2 is enabled.
10774868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10775868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ssl_data5.cert_request_info = cert_request.get();
10776868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10777868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net::StaticSocketDataProvider data5(
10778868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      data2_reads, arraysize(data2_reads), NULL, 0);
10779868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data5);
10780868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
107822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10783868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
107845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Begin the initial SSL handshake.
107865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
107875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
107885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_IO_PENDING, rv);
107895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the SSL handshake, which should abort due to requiring a
107915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // client certificate.
107925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
107935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
107945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Indicate that no certificate should be supplied. From the perspective
107965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of SSLClientCertCache, NULL is just as meaningful as a real
107975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate, so this is the same as supply a
107985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // legitimate-but-unacceptable certificate.
107995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithCertificate(NULL, callback.callback());
108005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_IO_PENDING, rv);
108015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure the certificate was added to the client auth cache before
108035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // allowing the connection to continue restarting.
108045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> client_cert;
108055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
108065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      HostPortPair("www.example.com", 443), &client_cert));
108075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(NULL, client_cert.get());
108085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restart the handshake. This will consume ssl_data2, which fails, and
108105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // then consume ssl_data3 and ssl_data4, both of which should also fail.
108115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The result code is checked against what ssl_data4 should return.
108125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
108135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
108145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that the client certificate is removed from the cache on a
108165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // handshake failure.
108175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
108185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      HostPortPair("www.example.com", 443), &client_cert));
108195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
108205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure that a client certificate is removed from the SSL client auth
108225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cache when:
108235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  1) An HTTPS proxy is involved.
108245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  3) The HTTPS proxy requests a client certificate.
108255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  4) The client supplies an invalid/unacceptable certificate for the
108265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     proxy.
108275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The test is repeated twice, first for connecting to an HTTPS endpoint,
108285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// then for connecting to an HTTP endpoint.
108297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
10830c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
108315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://proxy:70"));
108325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
10833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
108345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
108365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cert_request->host_and_port = HostPortPair("proxy", 70);
108375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
108395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data[1-3]. Rather than represending the endpoint
108405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (www.example.com:443), they represent failures with the HTTPS proxy
108415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (proxy:70).
108425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
108435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data1.cert_request_info = cert_request.get();
10844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
108455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10846c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
108475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
108495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data2.cert_request_info = cert_request.get();
10850c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
108515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
10852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
108535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
108555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0
108565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
108575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data3.cert_request_info = cert_request.get();
10858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
108595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
10860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
108615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
108625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestInfo requests[2];
108645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[0].url = GURL("https://www.example.com/");
108655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[0].method = "GET";
108665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[0].load_flags = net::LOAD_NORMAL;
108675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[1].url = GURL("http://www.example.com/");
108695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[1].method = "GET";
108705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[1].load_flags = net::LOAD_NORMAL;
108715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(requests); ++i) {
10873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->ResetNextMockIndexes();
10874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
108755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpNetworkTransaction> trans(
10876868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
108775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Begin the SSL handshake with the proxy.
108795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
108805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(
108815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &requests[i], callback.callback(), net::BoundNetLog());
108825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(net::ERR_IO_PENDING, rv);
108835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Complete the SSL handshake, which should abort due to requiring a
108855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // client certificate.
108865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
108875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
108885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Indicate that no certificate should be supplied. From the perspective
108905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // of SSLClientCertCache, NULL is just as meaningful as a real
108915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // certificate, so this is the same as supply a
108925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // legitimate-but-unacceptable certificate.
108935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithCertificate(NULL, callback.callback());
108945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(net::ERR_IO_PENDING, rv);
108955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ensure the certificate was added to the client auth cache before
108975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // allowing the connection to continue restarting.
108985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<X509Certificate> client_cert;
108995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
109005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        HostPortPair("proxy", 70), &client_cert));
109015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(NULL, client_cert.get());
109025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ensure the certificate was NOT cached for the endpoint. This only
109035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // applies to HTTPS requests, but is fine to check for HTTP requests.
109045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
109055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        HostPortPair("www.example.com", 443), &client_cert));
109065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Restart the handshake. This will consume ssl_data2, which fails, and
109085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // then consume ssl_data3, which should also fail. The result code is
109095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // checked against what ssl_data3 should return.
109105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
109115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
109125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Now that the new handshake has failed, ensure that the client
109145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // certificate was removed from the client auth cache.
109155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
109165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        HostPortPair("proxy", 70), &client_cert));
109175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
109185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        HostPortPair("www.example.com", 443), &client_cert));
109195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
109205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
109215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Unlike TEST/TEST_F, which are macros that expand to further macros,
109237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// TEST_P is a macro that expands directly to code that stringizes the
109247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// arguments. As a result, macros passed as parameters (such as prefix
109257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// or test_case_name) will not be expanded by the preprocessor. To
109267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// work around this, indirect the macro for TEST_P, so that the
109277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// pre-processor will expand macros such as MAYBE_test_name before
109287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// instantiating the test.
109297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#define WRAPPED_TEST_P(test_case_name, test_name) \
109307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TEST_P(test_case_name, test_name)
109317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
109325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Times out on Win7 dbg(2) bot. http://crbug.com/124776
109335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
109345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
109355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
109365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
109375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
109387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
10939cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
10940cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
109415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a special HttpNetworkSession with a MockCachingHostResolver.
10943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver.reset(new MockCachingHostResolver());
10944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
109455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
109465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pool_peer.DisableDomainAuthenticationVerification();
109475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
109497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
10950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
109515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host1_req(
1095390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
1095490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host2_req(
1095590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
109565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
109575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host1_req, 1),
109585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host2_req, 4),
109595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
109607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp(
109617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
109627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp_body(
109637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
109647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp(
109657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
109667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp_body(
109677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, true));
109685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
109695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp, 2),
109705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp_body, 3),
109715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp, 5),
109725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp_body, 6),
109735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 7),
109745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
109755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip;
109775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
109785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint peer_addr = IPEndPoint(ip, 443);
109795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect(ASYNC, OK, peer_addr);
109805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
109815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      connect,
109825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
109835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
10984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
109855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
109875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
109885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
109895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL("https://www.google.com/");
109905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
10991868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
109925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
109945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
109955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
109965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans1.GetResponseInfo();
109985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10999868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
110005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
110015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
110035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
110045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
110055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preload www.gmail.com into HostCache.
110075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair host_port("www.gmail.com", 443);
110085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostResolver::RequestInfo resolve_info(host_port);
110095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList ignored;
110103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  rv = session_deps_.host_resolver->Resolve(resolve_info,
110113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            DEFAULT_PRIORITY,
110123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            &ignored,
110133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            callback.callback(),
110143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            NULL,
110153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            BoundNetLog());
110165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
110175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
110185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
110195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
110215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
110225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL("https://www.gmail.com/");
110235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11024868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
110255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
110275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
110285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
110295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans2.GetResponseInfo();
110315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11032868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
110335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
110345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
110355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
110365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
110375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
110385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
110395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef MAYBE_UseIPConnectionPooling
110405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
11042cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
11043cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
110445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a special HttpNetworkSession with a MockCachingHostResolver.
11046c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver.reset(new MockCachingHostResolver());
11047c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
110485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
110495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pool_peer.DisableDomainAuthenticationVerification();
110505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
110527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
11053c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
110545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host1_req(
1105690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
1105790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host2_req(
1105890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
110595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
110605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host1_req, 1),
110615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host2_req, 4),
110625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
110637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp(
110647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
110657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp_body(
110667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
110677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp(
110687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
110697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp_body(
110707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, true));
110715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
110725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp, 2),
110735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp_body, 3),
110745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp, 5),
110755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp_body, 6),
110765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 7),
110775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
110785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip;
110805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
110815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint peer_addr = IPEndPoint(ip, 443);
110825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect(ASYNC, OK, peer_addr);
110835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
110845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      connect,
110855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
110865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
11087c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
110885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
110905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
110915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
110925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL("https://www.google.com/");
110935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11094868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
110955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
110975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
110985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
110995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans1.GetResponseInfo();
111015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
111035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
111045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
111065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
111075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
111085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
111105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
111115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL("https://www.gmail.com/");
111125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
111145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
111165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
111175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
111185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans2.GetResponseInfo();
111205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
111225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
111235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
111245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
111255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
111265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
111275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
111285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OneTimeCachingHostResolver : public net::HostResolver {
111305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
111315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
111325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : host_port_(host_port) {}
111335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~OneTimeCachingHostResolver() {}
111345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
111365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HostResolver methods:
111385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int Resolve(const RequestInfo& info,
111393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                      RequestPriority priority,
111405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      AddressList* addresses,
111415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const CompletionCallback& callback,
111425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      RequestHandle* out_req,
111435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const BoundNetLog& net_log) OVERRIDE {
111445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return host_resolver_.Resolve(
111453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        info, priority, addresses, callback, out_req, net_log);
111465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
111475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int ResolveFromCache(const RequestInfo& info,
111495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               AddressList* addresses,
111505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const BoundNetLog& net_log) OVERRIDE {
111515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
111525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv == OK && info.host_port_pair().Equals(host_port_))
111535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_resolver_.GetHostCache()->clear();
111545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
111555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
111565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CancelRequest(RequestHandle req) OVERRIDE {
111585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_resolver_.CancelRequest(req);
111595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
111605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockCachingHostResolver* GetMockHostResolver() {
111625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &host_resolver_;
111635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
111645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
111665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockCachingHostResolver host_resolver_;
111675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HostPortPair host_port_;
111685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
111695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Times out on Win7 dbg(2) bot. http://crbug.com/124776
111715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
11172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
111745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
11175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    UseIPConnectionPoolingWithHostCacheExpiration
111775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
111787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)WRAPPED_TEST_P(HttpNetworkTransactionTest,
111797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)               MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
111807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
111817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// prefix doesn't work with parametrized tests).
111827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
111837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return;
1118423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#else
11185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
11186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
111875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
111895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
111902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpNetworkSession::Params params =
11191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::CreateSessionParams(&session_deps_);
111925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.host_resolver = &host_resolver;
11193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
111945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
111955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pool_peer.DisableDomainAuthenticationVerification();
111965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
111987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
11199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
112005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1120190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host1_req(
1120290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
1120390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host2_req(
1120490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
112055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
112065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host1_req, 1),
112075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host2_req, 4),
112085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
112097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp(
112107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
112117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp_body(
112127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
112137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp(
112147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
112157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp_body(
112167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, true));
112175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
112185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp, 2),
112195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp_body, 3),
112205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp, 5),
112215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp_body, 6),
112225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 7),
112235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
112245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip;
112265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
112275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint peer_addr = IPEndPoint(ip, 443);
112285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect(ASYNC, OK, peer_addr);
112295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
112305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      connect,
112315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
112325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
11233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
112345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
112365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
112375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
112385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL("https://www.google.com/");
112395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
112415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
112435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
112445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
112455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans1.GetResponseInfo();
112475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
112495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
112505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
112525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
112535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
112545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preload cache entries into HostCache.
112565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
112575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList ignored;
112583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  rv = host_resolver.Resolve(resolve_info,
112593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             DEFAULT_PRIORITY,
112603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             &ignored,
112613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             callback.callback(),
112623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             NULL,
112633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             BoundNetLog());
112645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
112655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
112665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
112675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
112695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
112705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL("https://www.gmail.com/");
112715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
112735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
112755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
112765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
112775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans2.GetResponseInfo();
112795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
112815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
112825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
112835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
112845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
112855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
1128623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#endif
112875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
112885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
112895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
112915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string https_url = "https://www.google.com/";
112925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string http_url = "http://www.google.com:443/";
112935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTPS URL
1129590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(
1129690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
112975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes1[] = {
112995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req1, 0),
113005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
113015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
113037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
113045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads1[] = {
113055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp1, 1),
113065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body1, 2),
113075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 3)
113085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
113095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data1(
113115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1, reads1, arraysize(reads1),
113125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writes1, arraysize(writes1));
113135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect_data1(ASYNC, OK);
113145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1.set_connect_data(connect_data1);
113155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HTTP GET for the HTTP URL
113175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes2[] = {
113185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, 4,
113195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "GET / HTTP/1.1\r\n"
113205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com:443\r\n"
113215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
113225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
113235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads2[] = {
113255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
113265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 6, "hello"),
113275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 7, OK),
113285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
113295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data2(
113315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1, reads2, arraysize(reads2),
113325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writes2, arraysize(writes2));
113335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
113357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
11336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
11338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
113395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
113415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first transaction to set up the SpdySession
113435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
113445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
113455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL(https_url);
113465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(LOWEST, session.get());
113485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
113495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
113505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
1135190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
113525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
113545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
113555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, start the HTTP request
113575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
113585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
113595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL(http_url);
113605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
113625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
113635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
113645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1136590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
113665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
113685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
113695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
113705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
113725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string https_url = "https://www.google.com/";
113735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string http_url = "http://www.google.com:443/";
113745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTPS URL (through CONNECT tunnel)
113763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
113773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                LOWEST));
1137890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(
1137990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
113807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_req1(
113817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
11382c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
11383c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
11384c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SpdySynStreamIR req2_ir(3);
11385c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  spdy_util_.SetPriority(MEDIUM, &req2_ir);
11386c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  req2_ir.set_fin(true);
11387c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  req2_ir.SetHeader(spdy_util_.GetMethodKey(), "GET");
11388c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  req2_ir.SetHeader(spdy_util_.GetPathKey(),
11389c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                    spdy_util_.is_spdy2() ? http_url.c_str() : "/");
11390c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  req2_ir.SetHeader(spdy_util_.GetHostKey(), "www.google.com:443");
11391c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  req2_ir.SetHeader(spdy_util_.GetSchemeKey(), "http");
11392c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  spdy_util_.MaybeAddVersionHeader(&req2_ir);
11393c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_ptr<SpdyFrame> req2(
11394c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      spdy_util_.CreateFramer(false)->SerializeFrame(req2_ir));
113955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes1[] = {
113975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*connect, 0),
113985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*wrapped_req1, 2),
113995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2, 5),
114005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
114015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp(
114037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
114047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
114057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
114067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_resp1(
114077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
114087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body1(
114097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
114107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
114117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
114125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads1[] = {
114135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_resp, 1),
114145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_resp1, 3),
114155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body1, 4),
114165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2, 6),
114175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2, 7),
114185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 8)
114195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
114205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeterministicSocketData data1(reads1, arraysize(reads1),
114225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                writes1, arraysize(writes1));
114235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect_data1(ASYNC, OK);
114245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1.set_connect_data(connect_data1);
114255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
114272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
114282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog log;
11429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &log;
114305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
114317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl1.SetNextProto(GetParam());
11432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
114335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
114347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
11435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
114375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
11439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
114405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first transaction to set up the SpdySession
114425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
114435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
114445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL(https_url);
114455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11446868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(LOWEST, session.get());
114475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
114485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
114495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
1145090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
114515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1.RunFor(4);
114525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
114545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
114555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
114572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
114582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info1,
114592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
114602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
114615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, start the HTTP request
114625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
114635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
114645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL(http_url);
114655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11466868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
114675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
114685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
114695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1147090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
114715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1.RunFor(3);
114725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
114745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
114752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
114762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
114772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
114782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The established SPDY sessions is considered reused by the HTTP request.
114792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReusedWithPac(load_timing_info2);
114802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // HTTP requests over a SPDY session should have a different connection
114812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // socket_log_id than requests over a tunnel.
114822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
114835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
114845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
11486cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.force_spdy_always = true;
114875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string https_url = "https://www.google.com/";
114885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string http_url = "http://www.google.com:443/";
114895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTPS URL
1149190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(
1149290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
114935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for the HTTP URL
1149490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
1149590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
114965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
114985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req1, 1),
114995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2, 4),
115005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
115015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
115037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
115047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
115057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
115065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
115075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp1, 2),
115085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body1, 3),
115095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2, 5),
115105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2, 6),
115115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 7)
115125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
115135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data(reads, arraysize(reads),
115155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         writes, arraysize(writes));
115165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
115187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
11519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
115215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
115235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first transaction to set up the SpdySession
115255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
115265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
115275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL(https_url);
115285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(LOWEST, session.get());
115305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
115315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
115325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
1153390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
115345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
115365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
115375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, start the HTTP request
115395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
115405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
115415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL(http_url);
115425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11543868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
115445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
115455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
115465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1154790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
115485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
115505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
115515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
115525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that in the case where we have a SPDY session to a SPDY proxy
115545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that we do not pool other origins that resolve to the same IP when
115555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the certificate does not match the new origin.
115565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/134690
115577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
115585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string url1 = "http://www.google.com/";
115595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string url2 = "https://mail.google.com/";
115605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string ip_addr = "1.2.3.4";
115615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTP URL (through SPDY proxy)
115637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> headers(
115647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
11565a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyControlFrame(
115667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
115675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes1[] = {
115695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req1, 0),
115705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
115715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
115737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
115745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads1[] = {
115755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp1, 1),
115765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body1, 2),
115775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK, 3) // EOF
115785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
115795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeterministicSocketData> data1(
115815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new DeterministicSocketData(reads1, arraysize(reads1),
115825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  writes1, arraysize(writes1)));
115835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip;
115845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
115855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint peer_addr = IPEndPoint(ip, 443);
115865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect_data1(ASYNC, OK, peer_addr);
115875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1->set_connect_data(connect_data1);
115885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTPS URL (direct)
1159090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
1159190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
115925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes2[] = {
115945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2, 0),
115955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
115965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
115987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
115995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads2[] = {
116005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2, 1),
116015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2, 2),
116025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK, 3) // EOF
116035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
116045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeterministicSocketData> data2(
116065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new DeterministicSocketData(reads2, arraysize(reads2),
116075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  writes2, arraysize(writes2)));
116085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect_data2(ASYNC, OK);
116095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data2->set_connect_data(connect_data2);
116105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a proxy config that sends HTTP requests to a proxy, and
116125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // all others direct.
116135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig proxy_config;
116145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
116155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingProxyResolver* capturing_proxy_resolver =
116165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new CapturingProxyResolver();
11617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(new ProxyService(
116185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
116195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL));
116205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load a valid cert.  Note, that this does not need to
116225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be valid for proxy because the MockSSLClientSocket does
116235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not actually verify it.  But SpdySession will use this
116245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to see if it is valid for the new origin
116252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath certs_dir = GetTestCertsDirectory();
116265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> server_cert(
116275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ImportCertFromFile(certs_dir, "ok_cert.pem"));
116285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
116295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
116317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl1.SetNextProto(GetParam());
116325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl1.cert = server_cert;
11633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data1.get());
116365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
116387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
11639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data2.get());
116425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver.reset(new MockCachingHostResolver());
11644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
116465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
11648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
116495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first transaction to set up the SpdySession
116515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
116525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
116535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL(url1);
116545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11655868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(LOWEST, session.get());
116565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
116575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING,
116585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
116595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1->RunFor(3);
116605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(callback1.have_result());
116625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
116635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
116645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, start the HTTP request
116665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
116675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
116685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL(url2);
116695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11670868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
116715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
116725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
116735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1167490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
116755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data2->RunFor(3);
116765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(callback2.have_result());
116785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
116795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
116805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
116815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// error) in SPDY session, removes the socket from pool and closes the SPDY
11684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// session. Verify that new url's from the same HttpNetworkSession (and a new
11685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// SpdySession) do work. http://crbug.com/224701
116867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
11687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const std::string https_url = "https://www.google.com/";
11688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockRead reads1[] = {
11690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
11692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DeterministicSocketData> data1(
11694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  data1->SetStop(1);
11696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1169790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
1169890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
11699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockWrite writes2[] = {
11700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CreateMockWrite(*req2, 0),
11701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
11702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
117037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
117047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
11705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockRead reads2[] = {
11706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CreateMockRead(*resp2, 1),
11707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CreateMockRead(*body2, 2),
11708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, OK, 3)  // EOF
11709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
11710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DeterministicSocketData> data2(
11712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new DeterministicSocketData(reads2, arraysize(reads2),
11713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  writes2, arraysize(writes2)));
11714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SSLSocketDataProvider ssl1(ASYNC, OK);
117167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl1.SetNextProto(GetParam());
11717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data1.get());
11720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
117227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
11723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data2.get());
11726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
11728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
11729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Start the first transaction to set up the SpdySession and verify that
11731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // connection was closed.
11732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HttpRequestInfo request1;
11733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request1.method = "GET";
11734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request1.url = GURL(https_url);
11735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request1.load_flags = 0;
11736868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(MEDIUM, session.get());
11737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback1;
11738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
11739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
1174090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
11741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Now, start the second request and make sure it succeeds.
11744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HttpRequestInfo request2;
11745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request2.method = "GET";
11746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request2.url = GURL(https_url);
11747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request2.load_flags = 0;
11748868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
11749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback2;
11750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
11751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1175290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
11753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  data2->RunFor(3);
11754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(callback2.have_result());
11756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
11757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
11759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
117607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
11761cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
11762a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_group(
11763a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11764a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_pool(
11765a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11766a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11767a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Use two different hosts with different IPs so they don't get pooled.
11768a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11769a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11770a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11771a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11772a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SSLSocketDataProvider ssl1(ASYNC, OK);
117737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl1.SetNextProto(GetParam());
11774a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
117757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
11776a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11777a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11778a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1177990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
11780a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11781a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockWrite spdy1_writes[] = {
11782a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockWrite(*host1_req, 1),
11783a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
117847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp(
117857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
117867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp_body(
117877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
11788a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockRead spdy1_reads[] = {
11789a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockRead(*host1_resp, 2),
11790a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockRead(*host1_resp_body, 3),
11791a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 4),
11792a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
11793a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11794a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<OrderedSocketData> spdy1_data(
11795a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      new OrderedSocketData(
11796a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          spdy1_reads, arraysize(spdy1_reads),
11797a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          spdy1_writes, arraysize(spdy1_writes)));
11798a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11799a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1180090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
11801a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11802a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockWrite spdy2_writes[] = {
11803a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockWrite(*host2_req, 1),
11804a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
118057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp(
118067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
118077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp_body(
118087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
11809a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockRead spdy2_reads[] = {
11810a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockRead(*host2_resp, 2),
11811a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockRead(*host2_resp_body, 3),
11812a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 4),
11813a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
11814a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11815a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<OrderedSocketData> spdy2_data(
11816a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      new OrderedSocketData(
11817a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          spdy2_reads, arraysize(spdy2_reads),
11818a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          spdy2_writes, arraysize(spdy2_writes)));
11819a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11820a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11821a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockWrite http_write[] = {
11822a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
11823a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)              "Host: www.a.com\r\n"
11824a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
11825a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
11826a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11827a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockRead http_read[] = {
11828a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
11829a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11830a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead("Content-Length: 6\r\n\r\n"),
11831a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead("hello!"),
11832a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
11833a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11834a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                     http_write, arraysize(http_write));
11835a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11836a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11837a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HostPortPair host_port_pair_a("www.a.com", 443);
1183890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey spdy_session_key_a(
11839e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
11840a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
118417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11842a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11843a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  TestCompletionCallback callback;
11844a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HttpRequestInfo request1;
11845a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request1.method = "GET";
11846a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request1.url = GURL("https://www.a.com/");
11847a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request1.load_flags = 0;
11848a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans(
11849868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11850a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11851a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11852a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11853a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
11854a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11855a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
11856a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
11857868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
11858a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11859a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
11860a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
11861a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11862a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  std::string response_data;
11863a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11864a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("hello!", response_data);
11865a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  trans.reset();
11866a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(
118677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11868a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11869a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HostPortPair host_port_pair_b("www.b.com", 443);
1187090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey spdy_session_key_b(
11871e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
11872a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
118737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11874a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HttpRequestInfo request2;
11875a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request2.method = "GET";
11876a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request2.url = GURL("https://www.b.com/");
11877a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request2.load_flags = 0;
11878868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11879a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11880a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11881a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11882a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
11883a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11884a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  response = trans->GetResponseInfo();
11885a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
11886868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
11887a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11888a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
11889a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
11890a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11891a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("hello!", response_data);
11892a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
118937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11894a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(
118957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11896a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11897a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HostPortPair host_port_pair_a1("www.a.com", 80);
1189890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey spdy_session_key_a1(
11899e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
11900a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
119017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
11902a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HttpRequestInfo request3;
11903a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request3.method = "GET";
11904a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request3.url = GURL("http://www.a.com/");
11905a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request3.load_flags = 0;
11906868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11907a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11908a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11909a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11910a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
11911a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11912a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  response = trans->GetResponseInfo();
11913a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
11914868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
11915a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11916a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
11917a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(response->was_npn_negotiated);
11918a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11919a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("hello!", response_data);
11920a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
119217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11922a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
119237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11924a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
11925a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11926eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11927eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11928eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11929eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11930eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11931eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
119328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11933eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
119348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11935eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11936eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11937eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data;
11938eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  data.set_connect_data(mock_connect);
11939eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
11940eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11941eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
11942eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11943eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11944eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
11945eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11946eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
11947eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11948eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11949eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
11950eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11951eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // We don't care whether this succeeds or fails, but it shouldn't crash.
11952eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
11953eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  trans->GetFullRequestHeaders(&request_headers);
11954eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
11955eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11956eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11957eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11958eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11959eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11960eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11961eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
119628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11963eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
119648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11965eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11966eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11967eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data;
11968eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  data.set_connect_data(mock_connect);
11969eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
11970eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11971eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
11972eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11973eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11974eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
11975eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11976eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
11977eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11978eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11979eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
11980eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11981eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // We don't care whether this succeeds or fails, but it shouldn't crash.
11982eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
11983eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  trans->GetFullRequestHeaders(&request_headers);
11984eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
11985eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11986eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
11987eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11988eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11989eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11990eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11991eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
119928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11993eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
119948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11995eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11996eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
11997eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
11998eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
11999eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
12000eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
12001eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12002eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12003eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12004eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
12005eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
12006eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12007eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
12008eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12009eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12010eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
12011eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12012eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
12013eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12014eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12015eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
12016eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12017eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
12018eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12019eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.HasHeader("Host"));
12020eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
12021eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12022eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
12023eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
12024eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
12025eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
12026eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
12027eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
120288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12029eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
120308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12031eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12032eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
12033eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite(ASYNC, ERR_CONNECTION_RESET),
12034eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12035eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
12036eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
12037eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12038eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12039eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12040eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
12041eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
12042eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12043eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
12044eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12045eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12046eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
12047eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12048eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
12049eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12050eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12051eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
12052eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12053eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
12054eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12055eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.HasHeader("Host"));
12056eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
12057eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12058eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
12059eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
12060eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
12061eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
12062eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
12063eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
120648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12065eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
120668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12067eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12068eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
12069eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite("GET / HTTP/1.1\r\n"
12070eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Host: www.google.com\r\n"
12071eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Connection: keep-alive\r\n\r\n"),
12072eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12073eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
12074eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
12075eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12076eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12077eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12078eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
12079eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
12080eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12081eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
12082eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12083eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12084eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
12085eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12086eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
12087eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12088eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12089eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
12090eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12091eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
12092eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12093eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.HasHeader("Host"));
12094eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
12095eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12096eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
12097eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
12098eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
12099eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
12100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
12101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
121028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
121048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
12107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite("GET / HTTP/1.1\r\n"
12108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Host: www.google.com\r\n"
12109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Connection: keep-alive\r\n\r\n"),
12110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
12112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(ASYNC, ERR_CONNECTION_RESET),
12113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
12117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
12118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
12120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
12123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
12125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
12128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
12130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.HasHeader("Host"));
12132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
12133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
12135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
12136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
12137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
12138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
12139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.extra_headers.SetHeader("X-Foo", "bar");
12140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
121418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
121438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
12146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite("GET / HTTP/1.1\r\n"
12147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Host: www.google.com\r\n"
12148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Connection: keep-alive\r\n"
12149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "X-Foo: bar\r\n\r\n"),
12150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
12152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead("HTTP/1.1 200 OK\r\n"
12153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch             "Content-Length: 5\r\n\r\n"
12154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch             "hello"),
12155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(ASYNC, ERR_UNEXPECTED),
12156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
12160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
12161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
12163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
12166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
12168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(OK, rv);
12169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
12171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string foo;
12173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ("bar", foo);
12175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
12176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
121773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace {
121783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
121793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Fake HttpStreamBase that simply records calls to SetPriority().
121803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class FakeStream : public HttpStreamBase,
121813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   public base::SupportsWeakPtr<FakeStream> {
121823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
121833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  explicit FakeStream(RequestPriority priority) : priority_(priority) {}
121843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual ~FakeStream() {}
121853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
121863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RequestPriority priority() const { return priority_; }
121873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
121883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual int InitializeStream(const HttpRequestInfo* request_info,
121893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                               RequestPriority priority,
121903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                               const BoundNetLog& net_log,
121913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                               const CompletionCallback& callback) OVERRIDE {
121923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ERR_IO_PENDING;
121933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
121943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
121953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual int SendRequest(const HttpRequestHeaders& request_headers,
121963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          HttpResponseInfo* response,
121973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          const CompletionCallback& callback) OVERRIDE {
121983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
121993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ERR_UNEXPECTED;
122003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
122033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ERR_UNEXPECTED;
122053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
122083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                               const CompletionCallback& callback) OVERRIDE {
122093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ERR_UNEXPECTED;
122113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void Close(bool not_reusable) OVERRIDE {}
122143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool IsResponseBodyComplete() const OVERRIDE {
122163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
122183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool CanFindEndOfResponse() const OVERRIDE {
122213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
122223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool IsConnectionReused() const OVERRIDE {
122253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
122273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void SetConnectionReused() OVERRIDE {
122303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool IsConnectionReusable() const OVERRIDE {
122343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
122363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int64 GetTotalReceivedBytes() const OVERRIDE {
122395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ADD_FAILURE();
122405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return 0;
122415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
122425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
122433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool GetLoadTimingInfo(
122443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      LoadTimingInfo* load_timing_info) const OVERRIDE {
122453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
122473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
122503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void GetSSLCertRequestInfo(
122543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      SSLCertRequestInfo* cert_request_info) OVERRIDE {
122553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool IsSpdyHttpStream() const OVERRIDE {
122593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
122613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void Drain(HttpNetworkSession* session) OVERRIDE {
122643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void SetPriority(RequestPriority priority) OVERRIDE {
122683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    priority_ = priority;
122693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private:
122723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RequestPriority priority_;
122733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeStream);
122753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
122763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Fake HttpStreamRequest that simply records calls to SetPriority()
122783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// and vends FakeStreams with its current priority.
122793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class FakeStreamRequest : public HttpStreamRequest,
122803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          public base::SupportsWeakPtr<FakeStreamRequest> {
122813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
122823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeStreamRequest(RequestPriority priority,
122833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    HttpStreamRequest::Delegate* delegate)
122843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      : priority_(priority),
12285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        delegate_(delegate),
12286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        websocket_stream_create_helper_(NULL) {}
12287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  FakeStreamRequest(RequestPriority priority,
12289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    HttpStreamRequest::Delegate* delegate,
12290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    WebSocketHandshakeStreamBase::CreateHelper* create_helper)
12291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : priority_(priority),
12292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        delegate_(delegate),
12293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        websocket_stream_create_helper_(create_helper) {}
122943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual ~FakeStreamRequest() {}
122963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RequestPriority priority() const { return priority_; }
122983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const WebSocketHandshakeStreamBase::CreateHelper*
12300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  websocket_stream_create_helper() const {
12301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return websocket_stream_create_helper_;
12302f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
12303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
123043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Create a new FakeStream and pass it to the request's
123053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // delegate. Returns a weak pointer to the FakeStream.
123063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStream> FinishStreamRequest() {
123073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FakeStream* fake_stream = new FakeStream(priority_);
123083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Do this before calling OnStreamReady() as OnStreamReady() may
123093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // immediately delete |fake_stream|.
123103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
123113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
123123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return weak_stream;
123133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual int RestartTunnelWithProxyAuth(
123163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const AuthCredentials& credentials) OVERRIDE {
123173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
123183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ERR_UNEXPECTED;
123193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual LoadState GetLoadState() const OVERRIDE {
123223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
123233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return LoadState();
123243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void SetPriority(RequestPriority priority) OVERRIDE {
123273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    priority_ = priority;
123283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool was_npn_negotiated() const OVERRIDE {
123313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
123323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual NextProto protocol_negotiated() const OVERRIDE {
123353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return kProtoUnknown;
123363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool using_spdy() const OVERRIDE {
123393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
123403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private:
123433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RequestPriority priority_;
123443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpStreamRequest::Delegate* const delegate_;
12345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
123463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
123483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
123493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Fake HttpStreamFactory that vends FakeStreamRequests.
123513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class FakeStreamFactory : public HttpStreamFactory {
123523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
123533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeStreamFactory() {}
123543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual ~FakeStreamFactory() {}
123553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Returns a WeakPtr<> to the last HttpStreamRequest returned by
123573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // RequestStream() (which may be NULL if it was destroyed already).
123583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStreamRequest> last_stream_request() {
123593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return last_stream_request_;
123603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual HttpStreamRequest* RequestStream(
123633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const HttpRequestInfo& info,
123643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      RequestPriority priority,
123653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const SSLConfig& server_ssl_config,
123663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const SSLConfig& proxy_ssl_config,
123673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpStreamRequest::Delegate* delegate,
123683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const BoundNetLog& net_log) OVERRIDE {
123693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
123703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    last_stream_request_ = fake_request->AsWeakPtr();
123713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return fake_request;
123723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
123753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const HttpRequestInfo& info,
123763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      RequestPriority priority,
123773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const SSLConfig& server_ssl_config,
123783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const SSLConfig& proxy_ssl_config,
123793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpStreamRequest::Delegate* delegate,
12380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      WebSocketHandshakeStreamBase::CreateHelper* create_helper,
123813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const BoundNetLog& net_log) OVERRIDE {
12382f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FakeStreamRequest* fake_request =
12383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new FakeStreamRequest(priority, delegate, create_helper);
12384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    last_stream_request_ = fake_request->AsWeakPtr();
12385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return fake_request;
123863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void PreconnectStreams(int num_streams,
123893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                 const HttpRequestInfo& info,
123903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                 RequestPriority priority,
123913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                 const SSLConfig& server_ssl_config,
123923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                 const SSLConfig& proxy_ssl_config) OVERRIDE {
123933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
123943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE {
123973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
123983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return NULL;
123993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
124003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private:
124023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStreamRequest> last_stream_request_;
124033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
124053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
124063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// TODO(yhirano): Split this class out into a net/websockets file, if it is
12408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// worth doing.
12409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class FakeWebSocketStreamCreateHelper :
12410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      public WebSocketHandshakeStreamBase::CreateHelper {
12411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
12412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual WebSocketHandshakeStreamBase* CreateBasicStream(
12413f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      scoped_ptr<ClientSocketHandle> connection,
12414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      bool using_proxy) OVERRIDE {
12415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NOTREACHED();
12416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return NULL;
12417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
12418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12419f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual WebSocketHandshakeStreamBase* CreateSpdyStream(
12420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const base::WeakPtr<SpdySession>& session,
12421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      bool use_relative_url) OVERRIDE {
12422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NOTREACHED();
12423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return NULL;
12424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  };
12425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~FakeWebSocketStreamCreateHelper() {}
12427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual scoped_ptr<WebSocketStream> Upgrade() {
12429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NOTREACHED();
12430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return scoped_ptr<WebSocketStream>();
12431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
12432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
12433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
124343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}  // namespace
124353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Make sure that HttpNetworkTransaction passes on its priority to its
124373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// stream request on start.
124383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
124393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
124403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkSessionPeer peer(session);
124413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeStreamFactory* fake_factory = new FakeStreamFactory();
12442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
124433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkTransaction trans(LOW, session);
124453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
124473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo request;
124493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback callback;
124503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
124513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            trans.Start(&request, callback.callback(), BoundNetLog()));
124523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStreamRequest> fake_request =
124543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      fake_factory->last_stream_request();
124553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_request != NULL);
124563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(LOW, fake_request->priority());
124573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
124583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Make sure that HttpNetworkTransaction passes on its priority
124603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// updates to its stream request.
124613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
124623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
124633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkSessionPeer peer(session);
124643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeStreamFactory* fake_factory = new FakeStreamFactory();
12465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
124663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkTransaction trans(LOW, session);
124683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo request;
124703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback callback;
124713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
124723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            trans.Start(&request, callback.callback(), BoundNetLog()));
124733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStreamRequest> fake_request =
124753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      fake_factory->last_stream_request();
124763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_request != NULL);
124773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(LOW, fake_request->priority());
124783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  trans.SetPriority(LOWEST);
124803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_request != NULL);
124813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(LOWEST, fake_request->priority());
124823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
124833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Make sure that HttpNetworkTransaction passes on its priority
124853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// updates to its stream.
124863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
124873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
124883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkSessionPeer peer(session);
124893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeStreamFactory* fake_factory = new FakeStreamFactory();
12490f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
124913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkTransaction trans(LOW, session);
124933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo request;
124953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback callback;
124963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
124973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            trans.Start(&request, callback.callback(), BoundNetLog()));
124983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStreamRequest> fake_request =
125003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      fake_factory->last_stream_request();
125013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_request != NULL);
125023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
125033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_stream != NULL);
125043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(LOW, fake_stream->priority());
125053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  trans.SetPriority(LOWEST);
125073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(LOWEST, fake_stream->priority());
125083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
125093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
12511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The same logic needs to be tested for both ws: and wss: schemes, but this
12512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // test is already parameterised on NextProto, so it uses a loop to verify
12513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // that the different schemes work.
12514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
12515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (size_t i = 0; i < arraysize(test_cases); ++i) {
12516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    HttpNetworkSessionPeer peer(session);
12518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FakeStreamFactory* fake_factory = new FakeStreamFactory();
12519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
12520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    peer.SetHttpStreamFactoryForWebSocket(
12521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        scoped_ptr<HttpStreamFactory>(fake_factory));
12522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    HttpNetworkTransaction trans(LOW, session);
12524f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    trans.SetWebSocketHandshakeStreamCreateHelper(
12525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        &websocket_stream_create_helper);
12526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    HttpRequestInfo request;
12528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    TestCompletionCallback callback;
12529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    request.method = "GET";
12530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    request.url = GURL(test_cases[i]);
12531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12532f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING,
12533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              trans.Start(&request, callback.callback(), BoundNetLog()));
12534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::WeakPtr<FakeStreamRequest> fake_request =
12536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        fake_factory->last_stream_request();
12537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(fake_request != NULL);
12538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(&websocket_stream_create_helper,
12539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              fake_request->websocket_stream_create_helper());
12540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
12541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
12542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
125433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Tests that when a used socket is returned to the SSL socket pool, it's closed
125443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// if the transport socket pool is stalled on the global socket limit.
125453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
125463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_group(
125473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
125483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_pool(
125493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
125503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Set up SSL request.
125523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo ssl_request;
125543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ssl_request.method = "GET";
125553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ssl_request.url = GURL("https://www.google.com/");
125563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockWrite ssl_writes[] = {
125583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
125593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Host: www.google.com\r\n"
125603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
125613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
125623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockRead ssl_reads[] = {
125633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
125643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("Content-Length: 11\r\n\r\n"),
125653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("hello world"),
125663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
125673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
125683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
125693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                    ssl_writes, arraysize(ssl_writes));
125703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
125713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
125733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
125743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Set up HTTP request.
125763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo http_request;
125783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  http_request.method = "GET";
125793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  http_request.url = GURL("http://www.google.com/");
125803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockWrite http_writes[] = {
125823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
125833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Host: www.google.com\r\n"
125843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
125853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
125863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockRead http_reads[] = {
125873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
125883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("Content-Length: 7\r\n\r\n"),
125893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("falafel"),
125903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
125913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
125923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
125933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     http_writes, arraysize(http_writes));
125943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&http_data);
125953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
125973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Start the SSL request.
125993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback ssl_callback;
126003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<HttpTransaction> ssl_trans(
126013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
126023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING,
126033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            ssl_trans->Start(&ssl_request, ssl_callback.callback(),
126043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            BoundNetLog()));
126053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Start the HTTP request.  Pool should stall.
126073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback http_callback;
126083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<HttpTransaction> http_trans(
126093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
126103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING,
126113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            http_trans->Start(&http_request, http_callback.callback(),
126123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                              BoundNetLog()));
126133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(IsTransportSocketPoolStalled(session));
126143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Wait for response from SSL request.
126163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, ssl_callback.WaitForResult());
126173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string response_data;
126183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
126193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
126203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // The SSL socket should automatically be closed, so the HTTP request can
126223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // start.
126233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
126243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_FALSE(IsTransportSocketPoolStalled(session));
126253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // The HTTP request can now complete.
126273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, http_callback.WaitForResult());
126283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
126293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ("falafel", response_data);
126303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
126323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
126333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Tests that when a SSL connection is established but there's no corresponding
126353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// request that needs it, the new socket is closed if the transport socket pool
126363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// is stalled on the global socket limit.
126373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
126383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_group(
126393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
126403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_pool(
126413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
126423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Set up an ssl request.
126443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo ssl_request;
126463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ssl_request.method = "GET";
126473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ssl_request.url = GURL("https://www.foopy.com/");
126483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // No data will be sent on the SSL socket.
126503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StaticSocketDataProvider ssl_data;
126513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
126523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
126543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
126553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Set up HTTP request.
126573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo http_request;
126593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  http_request.method = "GET";
126603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  http_request.url = GURL("http://www.google.com/");
126613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockWrite http_writes[] = {
126633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
126643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Host: www.google.com\r\n"
126653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
126663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
126673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockRead http_reads[] = {
126683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
126693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("Content-Length: 7\r\n\r\n"),
126703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("falafel"),
126713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
126723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
126733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
126743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     http_writes, arraysize(http_writes));
126753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&http_data);
126763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
126783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Preconnect an SSL socket.  A preconnect is needed because connect jobs are
126803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // cancelled when a normal transaction is cancelled.
126813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
126823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  net::SSLConfig ssl_config;
126833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session->ssl_config_service()->GetSSLConfig(&ssl_config);
126843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
126853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                         ssl_config, ssl_config);
126863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
126873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Start the HTTP request.  Pool should stall.
126893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback http_callback;
126903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<HttpTransaction> http_trans(
126913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
126923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING,
126933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            http_trans->Start(&http_request, http_callback.callback(),
126943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                              BoundNetLog()));
126953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(IsTransportSocketPoolStalled(session));
126963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // The SSL connection will automatically be closed once the connection is
126983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // established, to let the HTTP request start.
126993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, http_callback.WaitForResult());
127003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string response_data;
127013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
127023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ("falafel", response_data);
127033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
127043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
127053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
127063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
127070529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
127080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
127090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
127100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
127110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
127130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
127140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
127150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
127160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
127170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
127190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
127200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
127210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
127220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
127230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
127240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
127250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
127260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
127270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
127280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
127290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
127310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
127320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("hello world"),
127330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
127340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
127350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
127360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
127370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
127380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
127400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
127420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
127430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
127450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
127460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
127480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_TRUE(response != NULL);
127490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response->headers.get() != NULL);
127510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
127520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string response_data;
127540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = ReadTransaction(trans.get(), &response_data);
127550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
127560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("hello world", response_data);
127570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
127580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// This test makes sure the retry logic doesn't trigger when reading an error
127600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// response from a server that rejected a POST with a CONNECTION_RESET.
127610529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest,
127620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       PostReadsErrorResponseAfterResetOnReusedSocket) {
127630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
127640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
127650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("GET / HTTP/1.1\r\n"
127660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
127670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n\r\n"),
127680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
127690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
127700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
127710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
127720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
127730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
127740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
127760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.1 200 Peachy\r\n"
127770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch             "Content-Length: 14\r\n\r\n"),
127780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("first response"),
127790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.1 400 Not OK\r\n"
127800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch             "Content-Length: 15\r\n\r\n"),
127810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("second response"),
127820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
127830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
127840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
127850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
127860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
127870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
127890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request1;
127900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request1.method = "GET";
127910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request1.url = GURL("http://www.foo.com/");
127920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request1.load_flags = 0;
127930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans1(
127950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
127960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
127970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
127980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
128000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
128010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
128030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_TRUE(response1 != NULL);
128040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response1->headers.get() != NULL);
128060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
128070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string response_data1;
128090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = ReadTransaction(trans1.get(), &response_data1);
128100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
128110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("first response", response_data1);
128120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Delete the transaction to release the socket back into the socket pool.
128130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  trans1.reset();
128140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
128160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
128170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
128180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request2;
128200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request2.method = "POST";
128210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request2.url = GURL("http://www.foo.com/");
128220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request2.upload_data_stream = &upload_data_stream;
128230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request2.load_flags = 0;
128240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans2(
128260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
128270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
128280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
128290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
128310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
128320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
128340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_TRUE(response2 != NULL);
128350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response2->headers.get() != NULL);
128370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
128380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string response_data2;
128400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = ReadTransaction(trans2.get(), &response_data2);
128410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
128420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("second response", response_data2);
128430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
128440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128450529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest,
128460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       PostReadsErrorResponseAfterResetPartialBodySent) {
128470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
128480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
128490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
128500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
128520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
128530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
128540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
128550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
128560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
128580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
128590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
128600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
128610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
128620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
128630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
128640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
128650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"
128660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "fo"),
128670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
128680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
128690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
128710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
128720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("hello world"),
128730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
128740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
128750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
128760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
128770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
128780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
128800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
128820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
128830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
128850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
128860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
128880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_TRUE(response != NULL);
128890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response->headers.get() != NULL);
128910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
128920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string response_data;
128940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = ReadTransaction(trans.get(), &response_data);
128950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
128960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("hello world", response_data);
128970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
128980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// This tests the more common case than the previous test, where headers and
129000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// body are not merged into a single request.
129010529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
129020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
129030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
129040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0);
129050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
129070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
129080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
129090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
129100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
129110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
129130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
129140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
129150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
129160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
129170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
129180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
129190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
129200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Transfer-Encoding: chunked\r\n\r\n"),
129210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
129220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
129230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
129250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
129260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("hello world"),
129270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
129280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
129290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
129300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
129310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
129320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
129340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
129360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
129370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Make sure the headers are sent before adding a chunk.  This ensures that
129380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // they can't be merged with the body in a single send.  Not currently
129390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // necessary since a chunked body is never merged with headers, but this makes
129400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // the test more future proof.
129410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::RunLoop().RunUntilIdle();
129420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  upload_data_stream.AppendChunk("last chunk", 10, true);
129440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
129460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
129470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
129490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_TRUE(response != NULL);
129500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response->headers.get() != NULL);
129520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
129530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string response_data;
129550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = ReadTransaction(trans.get(), &response_data);
129560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
129570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("hello world", response_data);
129580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
129590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129600529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
129610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
129620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
129630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
129640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
129660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
129670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
129680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
129690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
129700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
129720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
129730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
129740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
129760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
129770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
129780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
129790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
129800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
129810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
129820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
129840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
129850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
129860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("hello world"),
129870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
129880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
129890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
129900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
129910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
129920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
129940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
129960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
129970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
129990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
130000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
130020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_TRUE(response != NULL);
130030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response->headers.get() != NULL);
130050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
130060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string response_data;
130080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = ReadTransaction(trans.get(), &response_data);
130090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
130100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("hello world", response_data);
130110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
130120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130130529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
130140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
130150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
130160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
130170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
130190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
130200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
130210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
130220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
130230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
130250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
130260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
130270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
130280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
130290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
130300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
130310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
130320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
130330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
130340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
130350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
130370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
130380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("hello world"),
130390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
130400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
130410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
130420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
130430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
130440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
130460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
130480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
130490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
130510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
130520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
130540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response == NULL);
130550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
130560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130570529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest,
130580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       PostIgnoresNonErrorResponseAfterResetAnd100) {
130590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
130600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
130610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
130620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
130640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
130650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
130660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
130670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
130680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
130700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
130710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
130720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
130730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
130740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
130750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
130760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
130770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
130780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
130790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
130800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
130820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
130830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 302 Redirect\r\n"),
130840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("Location: http://somewhere-else.com/\r\n"),
130850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("Content-Length: 0\r\n\r\n"),
130860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
130870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
130880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
130890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
130900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
130910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
130930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
130950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
130960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
130980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
130990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
131010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response == NULL);
131020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
131030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131040529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
131050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
131060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
131070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
131080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
131100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
131110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
131120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
131130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
131140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
131160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
131170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
131180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
131190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
131200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
131210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
131220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
131230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
131240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
131250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
131260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
131280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP 0.9 rocks!"),
131290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
131300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
131310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
131320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
131330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
131340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
131360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
131380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
131390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
131410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
131420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
131440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response == NULL);
131450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
131460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131470529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
131480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
131490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
131500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
131510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
131530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
131540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
131550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
131560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
131570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
131590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
131600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
131610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
131620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
131630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
131640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
131650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
131660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
131670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
131680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
131690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
131710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
131720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
131730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
131740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
131750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
131760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
131770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
131790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
131810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
131820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
131840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
131850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
131870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response == NULL);
131880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
131890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
13191