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"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.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(
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
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)
436116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass BeforeProxyHeadersSentHandler {
437116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
438116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  BeforeProxyHeadersSentHandler()
439116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      : observed_before_proxy_headers_sent_(false) {}
440116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
441116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
442116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                HttpRequestHeaders* request_headers) {
443116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    observed_before_proxy_headers_sent_ = true;
444116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
445116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
446116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
447116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool observed_before_proxy_headers_sent() const {
448116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return observed_before_proxy_headers_sent_;
449116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
450116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
451116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string observed_proxy_server_uri() const {
452116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return observed_proxy_server_uri_;
453116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
454116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
455116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
456116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool observed_before_proxy_headers_sent_;
457116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string observed_proxy_server_uri_;
458116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
459116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler);
460116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
461116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fill |str| with a long header list that consumes >= |size| bytes.
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FillLargeHeadersString(std::string* str, int size) {
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* row =
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int sizeof_row = strlen(row);
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int num_rows = static_cast<int>(
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ceil(static_cast<float>(size) / sizeof_row));
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int sizeof_data = num_rows * sizeof_row;
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(sizeof_data >= size);
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  str->reserve(sizeof_data);
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < num_rows; ++i)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    str->append(row, sizeof_row);
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Alternative functions that eliminate randomness and dependency on the local
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// host name so that the generated NTLM messages are reproducible.
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockGenerateRandom1(uint8* output, size_t n) {
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const uint8 bytes[] = {
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static size_t current_byte = 0;
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < n; ++i) {
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    output[i] = bytes[current_byte++];
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_byte %= arraysize(bytes);
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MockGenerateRandom2(uint8* output, size_t n) {
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const uint8 bytes[] = {
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static size_t current_byte = 0;
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < n; ++i) {
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    output[i] = bytes[current_byte++];
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_byte %= arraysize(bytes);
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string MockGetHostName() {
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return "WTC-WIN7";
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename ParentPool>
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CaptureGroupNameSocketPool : public ParentPool {
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptureGroupNameSocketPool(HostResolver* host_resolver,
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             CertVerifier* cert_verifier);
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string last_group_name_received() const {
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return last_group_name_;
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int RequestSocket(const std::string& group_name,
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const void* socket_params,
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            RequestPriority priority,
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            ClientSocketHandle* handle,
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const CompletionCallback& callback,
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const BoundNetLog& net_log) {
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_group_name_ = group_name;
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_IO_PENDING;
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CancelRequest(const std::string& group_name,
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ClientSocketHandle* handle) {}
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ReleaseSocket(const std::string& group_name,
5283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             scoped_ptr<StreamSocket> socket,
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int id) {}
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CloseIdleSockets() {}
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int IdleSocketCount() const {
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int IdleSocketCountInGroup(const std::string& group_name) const {
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual LoadState GetLoadState(const std::string& group_name,
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const ClientSocketHandle* handle) const {
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return LOAD_STATE_IDLE;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual base::TimeDelta ConnectionTimeout() const {
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::TimeDelta();
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string last_group_name_;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameTransportSocketPool;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameHttpProxySocketPool;
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameSOCKSSocketPool;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameSSLSocketPool;
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename ParentPool>
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostResolver* host_resolver,
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CertVerifier* /* cert_verifier */)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<>
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostResolver* host_resolver,
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CertVerifier* /* cert_verifier */)
5681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : HttpProxyClientSocketPool(
5691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          0, 0, NULL, host_resolver, NULL, NULL, NULL, NULL) {}
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template <>
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostResolver* host_resolver,
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CertVerifier* cert_verifier)
575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : SSLClientSocketPool(0,
576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          0,
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          host_resolver,
579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          cert_verifier,
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
582a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          NULL,
583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          std::string(),
584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
5895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          false,
5905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          NULL) {
5915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper functions for validating that AuthChallengeInfo's are correctly
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// configured for common cases.
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_challenge)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(auth_challenge->is_proxy);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("MyRealm1", auth_challenge->realm);
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", auth_challenge->scheme);
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_challenge)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(auth_challenge->is_proxy);
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("MyRealm1", auth_challenge->realm);
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", auth_challenge->scheme);
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_challenge)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(auth_challenge->is_proxy);
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("digestive", auth_challenge->realm);
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("digest", auth_challenge->scheme);
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_challenge)
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(auth_challenge->is_proxy);
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(), auth_challenge->realm);
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("ntlm", auth_challenge->scheme);
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Basic) {
6408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
6421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SimpleGET) {
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", out.response_data);
6565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
6575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Response with no status line.
6617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", out.response_data);
6715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Allow up to 4 bytes of junk to precede status line.
6767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("DATA", out.response_data);
6865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
6875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Allow up to 4 bytes of junk to precede status line.
6917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("DATA", out.response_data);
7015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
7025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Beyond 4 bytes of slop and it should fail to find a status line.
7067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
7165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
7175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
7217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\n"),
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\n"),
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Q"),
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("J"),
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("DATA", out.response_data);
7355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
7365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Close the connection before enough bytes to have a status line.
7407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTT"),
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTT", out.response_data);
7505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
7515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Simulate a 204 response, lacking a Content-Length header, sent over a
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// persistent connection.  The response should still terminate since a 204
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cannot have a response body.
7577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StopsReading204) {
7585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  char junk[] = "junk";
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
7615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead(junk),  // Should not be read!!
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", out.response_data);
7695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
7705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 response_size = reads_size - strlen(junk);
7715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(response_size, out.totalReceivedBytes);
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A simple request using chunked encoding with some extra data after.
7757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
7765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string final_chunk = "0\r\n\r\n";
7775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string extra_data = "HTTP/1.1 200 OK\r\n";
7785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string last_read = final_chunk + extra_data;
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("5\r\nHello\r\n"),
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("1\r\n"),
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(" \r\n"),
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("5\r\nworld\r\n"),
7855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead(last_read.data()),
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello world", out.response_data);
7935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
7945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 response_size = reads_size - extra_data.size();
7955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(response_size, out.totalReceivedBytes);
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Next tests deal with http://crbug.com/56344.
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       MultipleContentLengthHeadersNoTransferEncoding) {
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n"),
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       DuplicateContentLengthHeadersNoTransferEncoding) {
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n"),
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello", out.response_data);
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ComplexContentLengthHeadersNoTransferEncoding) {
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // More than 2 dupes.
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads[] = {
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 200 OK\r\n"),
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n"),
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n"),
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n\r\n"),
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Hello"),
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                arraysize(data_reads));
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, out.rv);
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("Hello", out.response_data);
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HTTP/1.0
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads[] = {
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n"),
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n"),
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n\r\n"),
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Hello"),
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                arraysize(data_reads));
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, out.rv);
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("Hello", out.response_data);
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2 dupes and one mismatched.
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads[] = {
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 200 OK\r\n"),
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10\r\n"),
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10\r\n"),
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n\r\n"),
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                arraysize(data_reads));
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       MultipleContentLengthHeadersTransferEncoding) {
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 666\r\n"),
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 1337\r\n"),
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Transfer-Encoding: chunked\r\n\r\n"),
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("5\r\nHello\r\n"),
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("1\r\n"),
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(" \r\n"),
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("5\r\nworld\r\n"),
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello world", out.response_data);
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Next tests deal with http://crbug.com/98895.
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that a single Content-Disposition header results in no error.
8977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello", out.response_data);
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two identical Content-Disposition headers result in no error.
9127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       TwoIdenticalContentDispositionHeaders) {
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello", out.response_data);
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two distinct Content-Disposition headers result in an error.
9297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two identical Location headers result in no error.
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Also tests Location header behavior.
9447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Redirect\r\n"),
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://good.com/\r\n"),
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://good.com/\r\n"),
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://redirect.com/");
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
973868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsRedirect(&url));
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://good.com/", url);
978f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(response->proxy_server.IsEmpty());
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two distinct Location headers result in an error.
9827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Redirect\r\n"),
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://good.com/\r\n"),
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://evil.com/\r\n"),
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Do a request using the HEAD method. Verify that we don't try to read the
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// message body (since HEAD has none).
9977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Head) {
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "HEAD";
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1006116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  BeforeProxyHeadersSentHandler proxy_headers_handler;
1007116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  trans->SetBeforeProxyHeadersSentCallback(
1008116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1009116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::Unretained(&proxy_headers_handler)));
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("HEAD / HTTP/1.1\r\n"
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 404 Not Found\r\n"),
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Server: Blah\r\n"),
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 1234\r\n\r\n"),
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No response body because the test stops reading here.
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
1028c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the headers got parsed.
1042868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1234, response->headers->GetContentLength());
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
1045f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(response->proxy_server.IsEmpty());
1046116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string server_header;
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* iter = NULL;
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_server_header = response->headers->EnumerateHeader(
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &iter, "Server", &server_header);
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(has_server_header);
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Blah", server_header);
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reading should give EOF right away, since there is no message body
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (despite non-zero content-length).
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", response_data);
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
1064c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("world"),
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1074c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kExpectedResponseData[] = {
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "hello", "world"
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; ++i) {
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/");
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
1087868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response->headers.get() != NULL);
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_TRUE(response->proxy_server.IsEmpty());
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string response_data;
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ReadTransaction(trans.get(), &response_data);
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kExpectedResponseData[i], response_data);
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Ignores100) {
11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(new UploadBytesElementReader("foo", 3));
111468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.upload_data_stream = &upload_data_stream;
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
11241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test is almost the same as Ignores100 above, but the response contains
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HTTP/1.1 and the two status headers are read in one read.
11587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
11661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "HTTP/1.1 200 OK\r\n\r\n"),
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
12051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0),
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", response_data);
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
12361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0),
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockWrite* write_failure,
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockRead* read_failure) {
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
1262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
1263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Written data for successfully sending both requests.
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data1_writes[] = {
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.foo.com\r\n"
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.foo.com\r\n"
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read results for the first request.
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data1_reads[] = {
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (write_failure) {
128323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ASSERT_FALSE(read_failure);
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data1_writes[1] = *write_failure;
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(read_failure);
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data1_reads[2] = *read_failure;
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data1_writes, arraysize(data1_writes));
1292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data2_reads[] = {
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("world"),
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kExpectedResponseData[] = {
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "hello", "world"
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 first_socket_log_id = NetLog::Source::kInvalidId;
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; ++i) {
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
1311868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LoadTimingInfo load_timing_info;
13202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
13212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
13222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i == 0) {
13232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      first_socket_log_id = load_timing_info.socket_log_id;
13242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
13252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // The second request should be using a new socket.
13262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response->headers.get() != NULL);
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string response_data;
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ReadTransaction(trans.get(), &response_data);
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kExpectedResponseData[i], response_data);
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
134223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
134323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const MockWrite* write_failure,
1344effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const MockRead* read_failure,
1345effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    bool use_spdy) {
134623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  HttpRequestInfo request;
134723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  request.method = "GET";
1348effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  request.url = GURL("https://www.foo.com/");
134923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  request.load_flags = 0;
135023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
135123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  CapturingNetLog net_log;
135223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  session_deps_.net_log = &net_log;
135323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
135423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1355effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  SSLSocketDataProvider ssl1(ASYNC, OK);
1356effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  SSLSocketDataProvider ssl2(ASYNC, OK);
1357effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (use_spdy) {
1358effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ssl1.SetNextProto(GetParam());
1359effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ssl2.SetNextProto(GetParam());
1360effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
1361effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1362effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
1363effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1364effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // SPDY versions of the request and response.
1365effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1366effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1367effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<SpdyFrame> spdy_response(
1368effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1369effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<SpdyFrame> spdy_data(
1370effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
1371effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1372effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // HTTP/1.1 versions of the request and response.
1373effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1374effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      "Host: www.foo.com\r\n"
1375effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      "Connection: keep-alive\r\n\r\n";
1376effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1377effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const char kHttpData[] = "hello";
1378effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1379effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<MockRead> data1_reads;
1380effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<MockWrite> data1_writes;
138123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (write_failure) {
138223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ASSERT_FALSE(read_failure);
1383effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data1_writes.push_back(*write_failure);
1384effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data1_reads.push_back(MockRead(ASYNC, OK));
138523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  } else {
138623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ASSERT_TRUE(read_failure);
1387effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (use_spdy) {
1388effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      data1_writes.push_back(CreateMockWrite(*spdy_request));
1389effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    } else {
1390effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      data1_writes.push_back(MockWrite(kHttpRequest));
1391effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
1392effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data1_reads.push_back(*read_failure);
139323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
139423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1395effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1396effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                 &data1_writes[0], data1_writes.size());
139723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
139823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1399effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<MockRead> data2_reads;
1400effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<MockWrite> data2_writes;
1401effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1402effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (use_spdy) {
1403effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1404effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1405effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1406effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1407effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_reads.push_back(MockRead(ASYNC, OK, 3));
1408effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  } else {
1409effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_writes.push_back(
1410effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1411effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1412effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_reads.push_back(
1413effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1414effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1415effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_reads.push_back(MockRead(ASYNC, OK, 3));
1416effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
1417effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  OrderedSocketData data2(&data2_reads[0], data2_reads.size(),
1418effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                          &data2_writes[0], data2_writes.size());
141923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
142023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
142123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Preconnect a socket.
142223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  net::SSLConfig ssl_config;
142323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  session->ssl_config_service()->GetSSLConfig(&ssl_config);
1424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session->GetNextProtos(&ssl_config.next_protos);
142523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  session->http_stream_factory()->PreconnectStreams(
142623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
142723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Wait for the preconnect to complete.
142823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // TODO(davidben): Some way to wait for an idle socket count might be handy.
142923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  base::RunLoop().RunUntilIdle();
1430effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
143123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
143223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Make the request.
143323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  TestCompletionCallback callback;
143423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
143523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
143623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
143723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
143823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
143923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
144023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
144123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  rv = callback.WaitForResult();
144223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_EQ(OK, rv);
144323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
144423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  LoadTimingInfo load_timing_info;
144523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1446effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  TestLoadTimingNotReused(
1447effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      load_timing_info,
1448effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
144923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
145023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
145123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
145223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
145323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
145423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
145523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
145623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  std::string response_data;
145723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
145823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_EQ(OK, rv);
1459effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(kHttpData, response_data);
146023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
146123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
14627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       KeepAliveConnectionNotConnectedOnWrite) {
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeepAliveConnectionResendRequestTest(&write_failure, NULL);
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeepAliveConnectionResendRequestTest(NULL, &read_failure);
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead read_failure(SYNCHRONOUS, OK);  // EOF
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeepAliveConnectionResendRequestTest(NULL, &read_failure);
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
147846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Make sure that on a 408 response (Request Timeout), the request is retried,
147946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// if the socket was a reused keep alive socket.
148046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
148146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  MockRead read_failure(SYNCHRONOUS,
148246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "HTTP/1.1 408 Request Timeout\r\n"
148346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "Connection: Keep-Alive\r\n"
148446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "Content-Length: 6\r\n\r\n"
148546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "Pickle");
148646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  KeepAliveConnectionResendRequestTest(NULL, &read_failure);
148746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
148846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
148923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
149023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)       PreconnectErrorNotConnectedOnWrite) {
149123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1492effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(&write_failure, NULL, false);
149323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
149423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
149523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
149623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1497effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(NULL, &read_failure, false);
149823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
149923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
150023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
150123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  MockRead read_failure(SYNCHRONOUS, OK);  // EOF
1502effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1503effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
1504effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1505effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1506effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MockRead read_failure(ASYNC, OK);  // EOF
1507effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1508effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
1509effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
151046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Make sure that on a 408 response (Request Timeout), the request is retried,
151146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// if the socket was a preconnected (UNUSED_IDLE) socket.
151246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
151346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  MockRead read_failure(SYNCHRONOUS,
151446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "HTTP/1.1 408 Request Timeout\r\n"
151546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "Connection: Keep-Alive\r\n"
151646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "Content-Length: 6\r\n\r\n"
151746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "Pickle");
151846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  KeepAliveConnectionResendRequestTest(NULL, &read_failure);
151946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  PreconnectErrorResendRequestTest(NULL, &read_failure, false);
152046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
152146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1522effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(HttpNetworkTransactionTest,
1523effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch       SpdyPreconnectErrorNotConnectedOnWrite) {
1524effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1525effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1526effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
1527effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1528effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1529effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1530effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1531effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
1532effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1533effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1534effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MockRead read_failure(SYNCHRONOUS, OK);  // EOF
1535effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1536effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
1537effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1538effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1539effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MockRead read_failure(ASYNC, OK);  // EOF
1540effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(NULL, &read_failure, true);
154123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
154223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
15437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
15511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_CONNECTION_RESET),
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response == NULL);
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// What do various browsers do when the server closes a non-keepalive
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection without sending any response header or body?
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IE7: error page
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Safari 3.1.2 (Windows): error page
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Firefox 3.0.1: blank page
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Opera 9.52: after five attempts, blank page
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Us: error page (EMPTY_RESPONSE)
15837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),  // EOF
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test that network access can be deferred and resumed.
15965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
15975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  HttpRequestInfo request;
15985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.method = "GET";
15995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
16005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.load_flags = 0;
16015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
16045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Defer on OnBeforeNetworkStart.
16075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BeforeNetworkStartHandler net_start_handler(true);  // defer
16085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  trans->SetBeforeNetworkStartCallback(
16095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
16105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(&net_start_handler)));
16115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MockRead data_reads[] = {
16135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
16145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
16155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead("hello"),
16165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead(SYNCHRONOUS, 0),
16175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
16185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
16195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
16205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestCompletionCallback callback;
16225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
16245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
16255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
16265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Should have deferred for network start.
16285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(net_start_handler.observed_before_network_start());
16295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
16305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(trans->GetResponseInfo() == NULL);
16315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  trans->ResumeNetworkStart();
16335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rv = callback.WaitForResult();
16345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(OK, rv);
16355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(trans->GetResponseInfo() != NULL);
16365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
16385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
16395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
16405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    rv = callback.WaitForResult();
16415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(5, rv);
16425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  trans.reset();
16435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
16445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test that network use can be deferred and canceled.
16465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
16475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  HttpRequestInfo request;
16485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.method = "GET";
16495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
16505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.load_flags = 0;
16515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
16545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Defer on OnBeforeNetworkStart.
16575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BeforeNetworkStartHandler net_start_handler(true);  // defer
16585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  trans->SetBeforeNetworkStartCallback(
16595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
16605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(&net_start_handler)));
16615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestCompletionCallback callback;
16635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
16655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
16665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
16675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Should have deferred for network start.
16695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(net_start_handler.observed_before_network_start());
16705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
16715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(trans->GetResponseInfo() == NULL);
16725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
16735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// tests. There was a bug causing HttpNetworkTransaction to hang in the
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destructor in such situations.
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See http://crbug.com/154712 and http://crbug.com/156609.
16787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1686868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: keep-alive\r\n"),
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, 0),
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1707868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, rv);
1711868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
171590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1727868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: keep-alive\r\n"),
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, 0),
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1747868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
175390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we correctly reuse a keep-alive connection after not explicitly
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reading the body.
17597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
1766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
1767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that because all these reads happen in the same
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // StaticSocketDataProvider, it shows that the same socket is being reused for
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // all transactions.
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data1_reads[] = {
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Found\r\n"
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 0\r\n\r\n"),
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Found\r\n"
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 5\r\n\r\n"
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "hello"),
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 301 Moved Permanently\r\n"
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 0\r\n\r\n"),
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 301 Moved Permanently\r\n"
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 5\r\n\r\n"
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "hello"),
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
1790c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data2_reads[] = {
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1796c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kNumUnreadBodies = arraysize(data1_reads) - 2;
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_lines[kNumUnreadBodies];
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 first_socket_log_id = NetLog::Source::kInvalidId;
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
1806868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LoadTimingInfo load_timing_info;
18152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
18162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i == 0) {
18172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
18182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      first_socket_log_id = load_timing_info.socket_log_id;
18192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
18202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestLoadTimingReused(load_timing_info);
18212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
18222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
18232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1827868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ASSERT_TRUE(response->headers.get() != NULL);
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_lines[i] = response->headers->GetStatusLine();
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We intentionally don't read the response bodies.
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kStatusLines[] = {
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 204 No Content",
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 205 Reset Content",
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 304 Not Modified",
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 302 Found",
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 302 Found",
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 301 Moved Permanently",
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 301 Moved Permanently",
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 forgot_to_update_kStatusLines);
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kNumUnreadBodies; ++i)
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kStatusLines[i], response_lines[i]);
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
18502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1851868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
1858868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello", response_data);
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth.
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (basic auth is the easiest to mock, because it has no randomness).
18687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuth) {
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog log;
1875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &log;
18768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
18781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Give a couple authenticate options (only the middle one is actually
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // supported).
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Large content-length -- won't matter, as connection will be reset.
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10000\r\n\r\n"),
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), this is the request we should
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be issuing -- the final header line contains the credentials.
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
1920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
1921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
19322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
19332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
19342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
19365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
19375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
19522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
19532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
19542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The load timing after restart should have a new socket ID, and times after
19552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // those of the first load timing.
19562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info1.receive_headers_end,
19572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info2.connect_timing.connect_start);
19582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
19592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
19615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
19625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
19771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Large content-length -- won't matter, as connection will be reset.
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10000\r\n\r\n"),
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
1996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, rv);
20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
20065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
20075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection.
20157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog log;
2022c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &log;
2023c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 14\r\n\r\n"),
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Unauthorized\r\n"),
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly, the server responds with the actual content.
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If there is a regression where we disconnect a Keep-Alive
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection during an auth roundtrip, we'll end up reading this.
20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NULL, 0);
2062c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
2063c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2068868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
20762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
20772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
20782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
20932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
20942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info2);
20952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The load timing after restart should have the same socket ID, and times
20962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // those of the first load timing.
20972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info1.receive_headers_end,
20982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info2.send_start);
20992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
21002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
21055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
21065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string response_data;
21075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
21085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(OK, rv);
21095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
21105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection and with no response body to drain.
21157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly, the server responds with the actual content.
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An incorrect reconnect would cause this to be read.
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NULL, 0);
2157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
2158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection and with a large response body to drain.
21917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Respond with 5 kb of response body.
22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string large_body_string("Unauthorized");
22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  large_body_string.append(5 * 1024, ' ');
22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  large_body_string.append("\r\n");
22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 5134 = 12 + 5 * 1024 + 2
22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5134\r\n\r\n"),
22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly, the server responds with the actual content.
22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An incorrect reconnect would cause this to be read.
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NULL, 0);
2241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
2242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection, but the server gets impatient and closes the connection.
22757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This simulates the seemingly successful write to a closed connection
22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // if the bug is not fixed.
22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 14\r\n\r\n"),
23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Tell MockTCPClientSocket to simulate the server closing the connection.
23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Unauthorized\r\n"),
23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),  // The server closes the connection.
23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), this is the request we should
23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be issuing -- the final header line contains the credentials.
23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
2327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
2328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a connection
23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that requires a restart when setting up an SSL tunnel.
23617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the no authentication data flag is set.
23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
2369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
23702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No credentials.
23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Connection: close\r\n\r\n"),
24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, "hello"),
24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2418868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
24432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CONNECT requests and responses are handled at the connect job level, so
24442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the transaction does not yet have a connection.
24452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
24462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
24682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
24692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
24702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// proxy connection, when setting up an SSL tunnel.
24777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that proxy authentication is attempted even
24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the no authentication data flag is set.
24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
2486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2492868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No credentials.
25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
25155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("0123456789"),
25165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Wrong credentials (wrong password).
25185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
25195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
25215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No response body because the test stops reading here.
25225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
25235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
25245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
25355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
25365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
25375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
25385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
25395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
25405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
25415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
25425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
25435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
25445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
25455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
25475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2548868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
25495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
25515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, response->headers->GetContentLength());
25525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
25535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
25565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wrong password (should be "bar").
25585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
25595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBaz), callback2.callback());
25605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
25615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
25635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
25645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
25665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2567868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
25685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
25695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
25705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, response->headers->GetContentLength());
25715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
25725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
25735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Flush the idle socket before the NetLog and HttpNetworkTransaction go
25755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // out of scope.
25765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
25775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we don't read the response body when we fail to establish a tunnel,
25805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// even if the user cancels the proxy's auth attempt.
25817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
25825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
25835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
25845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
25855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
25865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
2588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
25895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
25915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2593868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
25945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
25965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
25975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
25985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
26005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
26015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 407.
26035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
26045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
26065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
26075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
26085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
2612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
26155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
26175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
26205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
26235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
26245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
26265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
26275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, response->headers->GetContentLength());
26285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
26295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
26315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
26325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
26335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
26355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
26365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
26395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
26407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
26415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
26425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
26455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We are using a DIRECT connection (i.e. no proxy) for this session.
26478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
26491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
26505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
26555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
26595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
26605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Large content-length -- won't matter, as connection will be reset.
26615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10000\r\n\r\n"),
26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
26635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
26645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
26665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
26685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
26705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
26735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
26755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// through a non-authenticating proxy. The request should fail with
26805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ERR_UNEXPECTED_PROXY_AUTH.
26815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that it is impossible to detect if an HTTP server returns a 407 through
26825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a non-authenticating proxy - there is nothing to indicate whether the
26835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// response came from the proxy or the server, so it is treated as if the proxy
26845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// issued the challenge.
26857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       HttpsServerRequestsProxyAuthThroughProxy) {
26875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
26925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
26955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
26985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
27035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
27045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
27085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
27095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Unauthorized\r\n"),
27115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
27125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\r\n"),
27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
27145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
27175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
27195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
27235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2725868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
27285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
27315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
27325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
27335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
27345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
27365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
27375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
27385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
27395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
27405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
27415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test the load timing for HTTPS requests with an HTTP proxy.
27447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
27452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
27462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
27472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("https://www.google.com/1");
27482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
27502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
27512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("https://www.google.com/2");
27522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against proxy server "myproxy:70".
2754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
27552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixed("PROXY myproxy:70"));
27562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
2757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
27592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
27612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite data_writes1[] = {
27622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
27632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
27642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
27652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET /1 HTTP/1.1\r\n"
27672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
27682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
27692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET /2 HTTP/1.1\r\n"
27712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
27722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
27732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
27742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
27762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // connection.
27772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead data_reads1[] = {
27782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
27792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
27812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Length: 1\r\n\r\n"),
27822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, "1"),
27832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
27852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Length: 2\r\n\r\n"),
27862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, "22"),
27872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
27882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
27902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
27922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
27942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback1;
27962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans1(
2797868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
27982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans1->Start(&request1, callback1.callback(), log.bound());
28002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
28012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback1.WaitForResult();
28032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
28042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
28062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response1 != NULL);
2807868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response1->headers.get() != NULL);
28082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, response1->headers->GetContentLength());
28092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
28112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
28122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
28132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans1.reset();
28152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback2;
28172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
2818868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
28192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback2.callback(), log.bound());
28212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
28222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback2.WaitForResult();
28242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
28252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
28272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response2 != NULL);
2828868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response2->headers.get() != NULL);
28292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, response2->headers->GetContentLength());
28302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
28322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
28332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info2);
28342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
28362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans2.reset();
28382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  session->CloseAllConnections();
28392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
28402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
28427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
28432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
28442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
28452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("https://www.google.com/1");
28462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
28482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
28492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("https://www.google.com/2");
28502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against proxy server "myproxy:70".
2852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
28532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
28542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
2855c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
28572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
28592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite data_writes1[] = {
28602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
28612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
28622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
28632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET /1 HTTP/1.1\r\n"
28652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
28662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
28672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET /2 HTTP/1.1\r\n"
28692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
28702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
28712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
28722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
28742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // connection.
28752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead data_reads1[] = {
28762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
28772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
28792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Length: 1\r\n\r\n"),
28802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, "1"),
28812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
28832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Length: 2\r\n\r\n"),
28842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, "22"),
28852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
28862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
28882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
28902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
28922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback1;
28942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans1(
2895868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
28962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans1->Start(&request1, callback1.callback(), log.bound());
28982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
28992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback1.WaitForResult();
29012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
29022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
29042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response1 != NULL);
2905868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response1->headers.get() != NULL);
29062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, response1->headers->GetContentLength());
29072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
29092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
29102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info1,
29112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
29122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans1.reset();
29142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback2;
29162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
2917868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
29182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback2.callback(), log.bound());
29202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
29212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback2.WaitForResult();
29232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
29242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
29262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response2 != NULL);
2927868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response2->headers.get() != NULL);
29282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, response2->headers->GetContentLength());
29292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
29312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
29322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReusedWithPac(load_timing_info2);
29332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
29352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans2.reset();
29372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  session->CloseAllConnections();
29382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
29392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a simple get through an HTTPS Proxy.
29417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
29425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
29435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
29445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
29455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
2947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
29485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
29495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
29525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should use full url
29545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
29555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
29565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
29575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
29585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
29595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
29615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
29625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
29635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
29645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
29655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
29665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
29685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
29705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
29725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
29745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2976868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
29775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
29795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
29805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
29825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
29835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
29852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
29862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
29872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
29882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
29905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
29915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
29935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
29945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
29955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
29965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
29985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
29995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
30005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY get through an HTTPS Proxy.
30027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
30035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
30045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
30055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
30065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
30075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
3009c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
30105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
30115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3012c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3013c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
30145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetch http://www.google.com/ via SPDY
301690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
301790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
30185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
30195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
30217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
30225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
30235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
30245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data),
30255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
30265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
30275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
30295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
30305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
30315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3032c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
30335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
30357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3036c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
30375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
30395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3041868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
30425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
30445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
30455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
30475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
30485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
30502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
30512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
30522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
30532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
30555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
3056868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
30575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
30585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
30605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
30615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUploadData, response_data);
30625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
30635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// Verifies that a session which races and wins against the owning transaction
30656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// (completing prior to host resolution), doesn't fail the transaction.
30666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// Regression test for crbug.com/334413.
30676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
30686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  HttpRequestInfo request;
30696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  request.method = "GET";
30706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
30716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  request.load_flags = 0;
30726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Configure SPDY proxy server "proxy:70".
30746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.proxy_service.reset(
30756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      ProxyService::CreateFixed("https://proxy:70"));
30766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  CapturingBoundNetLog log;
30776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
30786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
30796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Fetch http://www.google.com/ through the SPDY proxy.
30816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_ptr<SpdyFrame> req(
30826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
30836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  MockWrite spdy_writes[] = {CreateMockWrite(*req)};
30846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
30866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
30876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  MockRead spdy_reads[] = {
30886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      CreateMockRead(*resp), CreateMockRead(*data), MockRead(ASYNC, 0, 0),
30896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  };
30906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  DelayedSocketData spdy_data(
30926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      1,  // wait for one write to finish before reading.
30936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      spdy_reads,
30946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      arraysize(spdy_reads),
30956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      spdy_writes,
30966d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      arraysize(spdy_writes));
30976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
30986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
31006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ssl.SetNextProto(GetParam());
31016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
31026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  TestCompletionCallback callback1;
31046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
31066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
31076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Stall the hostname resolution begun by the transaction.
31096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.host_resolver->set_synchronous_mode(false);
31106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.host_resolver->set_ondemand_mode(true);
31116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
31136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
31146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Race a session to the proxy, which completes first.
31166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.host_resolver->set_ondemand_mode(false);
31176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  SpdySessionKey key(
31186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
31196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  base::WeakPtr<SpdySession> spdy_session =
31206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      CreateSecureSpdySession(session, key, log.bound());
31216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Unstall the resolution begun by the transaction.
31236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.host_resolver->set_ondemand_mode(true);
31246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.host_resolver->ResolveAllPending();
31256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_FALSE(callback1.have_result());
31276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  rv = callback1.WaitForResult();
31286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_EQ(OK, rv);
31296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
31316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
31326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
31336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
31346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  std::string response_data;
31366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
31376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_EQ(kUploadData, response_data);
31386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
31396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY get through an HTTPS Proxy.
31417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
31425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
31435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
31445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
31455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
31465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
3148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
31495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://myproxy:70"));
31505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
31535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first request will be a bare GET, the second request will be a
31555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GET with a Proxy-Authorization header.
31565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> req_get(
315790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
31585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kExtraAuthorizationHeaders[] = {
315990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "proxy-authorization", "Basic Zm9vOmJhcg=="
31605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
31615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> req_get_authorization(
316290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
316390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  arraysize(kExtraAuthorizationHeaders) / 2,
316490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  false,
316590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  3,
316690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  LOWEST,
316790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  false));
31685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
31695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req_get, 1),
31705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req_get_authorization, 4),
31715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
31725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first response is a 407 proxy authentication challenge, and the second
31745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // response will be a 200 response since the second request includes a valid
31755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Authorization header.
31765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kExtraAuthenticationHeaders[] = {
317790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "proxy-authenticate", "Basic realm=\"MyRealm1\""
31785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
31795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp_authentication(
31807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdySynReplyError(
31815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "407 Proxy Authentication Required",
31825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
31835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          1));
31845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> body_authentication(
31857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
31867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp_data(
31877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
31887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
31895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
31905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp_authentication, 2),
31915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body_authentication, 3),
31925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp_data, 5),
31935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body_data, 6),
31945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 7),
31955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
31965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data(
31985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
31995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
32015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
32037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
32055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
32075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
32105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
32125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
32135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
32155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
32165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* const response = trans->GetResponseInfo();
32185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
3220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
32215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
32225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
32235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
32245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
32265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
32285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
32295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
32305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
32325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
32335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
32355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response_restart != NULL);
3237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response_restart->headers.get() != NULL);
32385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response_restart->headers->response_code());
32395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
32405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
32415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
32447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
32455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
32465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
32475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
32485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
32495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
3251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
32525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
32535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
32565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
32595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY
32613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
32623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                LOWEST));
32635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetch https://www.google.com/ via HTTP
32645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char get[] = "GET / HTTP/1.1\r\n"
32665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Host: www.google.com\r\n"
32675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Connection: keep-alive\r\n\r\n";
32685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get(
32697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
32707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp(
32717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
32725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char resp[] = "HTTP/1.1 200 OK\r\n"
32735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 10\r\n\r\n";
32745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp(
32757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
32765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body(
32777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
32785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> window_update(
327990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
32805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
32825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*connect, 1),
32835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*wrapped_get, 3),
328490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      CreateMockWrite(*window_update, 5),
32855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
32865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
32885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_resp, 2, ASYNC),
32895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_get_resp, 4, ASYNC),
32905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body, 6, ASYNC),
32915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body, 7, ASYNC),
32925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 8),
32935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
32945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
32965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
32975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
32995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
33017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
33035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
33045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl2.was_npn_negotiated = false;
33055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl2.protocol_negotiated = kProtoUnknown;
3306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
33075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
33095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
33115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
33125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
33145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
33155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
33172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
33182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
33192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
33215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
3322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
33235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
33245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
33265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
33275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("1234567890", response_data);
33285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
33295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
33317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
33325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
33335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
33345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
33355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
33365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
3338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
33395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
33405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
33435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
33465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY
33483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
33493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                LOWEST));
33505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetch https://www.google.com/ via SPDY
33515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kMyUrl = "https://www.google.com/";
335290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> get(
335390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
33547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get(
33557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(get, 1));
33567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp(
33577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
33587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> get_resp(
33597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
33605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp(
33617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
33627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
33637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body(
33647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(body, 1));
33655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> window_update_get_resp(
336690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
33675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> window_update_body(
336890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
33695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
33715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*connect, 1),
33725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*wrapped_get, 3),
33735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*window_update_get_resp, 5),
33745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*window_update_body, 7),
33755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
33765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
33785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_resp, 2, ASYNC),
33795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_get_resp, 4, ASYNC),
33805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body, 6, ASYNC),
33815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 8),
33825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
33835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
33855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
33865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
33885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
33907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
33925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
33937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
33947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.protocol_negotiated = GetParam();
3395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
33965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
33985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
34005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
34015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
34035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
34045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
34062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
34072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
34082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
34105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
3411868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
34125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
34135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
34155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
34165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUploadData, response_data);
34175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY CONNECT failure through an HTTPS Proxy.
34207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
34215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
34225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
34235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
34245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
34255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
3427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
34285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
34295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
34325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
34355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY
34373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
34383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                LOWEST));
343990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> get(
344090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
34415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
34435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*connect, 1),
34445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*get, 3),
34455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
34465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
34487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
34495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
34505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp, 2, ASYNC),
34515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 4),
34525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
34535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
34555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
34565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
34585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
34607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
34625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
34637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
3464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
34655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
34675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
34695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
34705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
34725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
34735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(ttuttle): Anything else to check here?
34755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
34782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// HTTPS Proxy to different servers.
34797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
34802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
34812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against https proxy server "proxy:70".
3482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
34832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "https://proxy:70"));
34842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
3485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
34862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
3487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
34882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
34902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
34912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("https://www.google.com/");
34922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.load_flags = 0;
34932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
34952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
34962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("https://news.google.com/");
34972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.load_flags = 0;
34982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY.
35003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
35013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                 LOWEST));
35027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp1(
35037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
35042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fetch https://www.google.com/ via HTTP.
35062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char get1[] = "GET / HTTP/1.1\r\n"
35072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Host: www.google.com\r\n"
35082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Connection: keep-alive\r\n\r\n";
35092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get1(
35107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
35112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char resp1[] = "HTTP/1.1 200 OK\r\n"
35122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Content-Length: 1\r\n\r\n";
35132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp1(
35147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
35157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body1(
35167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
35172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> window_update(
351890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
35192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CONNECT to news.google.com:443 via SPDY.
3521116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SpdyHeaderBlock connect2_block;
3522116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
3523116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  connect2_block[spdy_util_.GetPathKey()] = "news.google.com:443";
3524116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  connect2_block[spdy_util_.GetHostKey()] = "news.google.com";
3525116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  spdy_util_.MaybeAddVersionHeader(&connect2_block);
35262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> connect2(
3527116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
3528c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
35297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp2(
35307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
35312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fetch https://news.google.com/ via HTTP.
35332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char get2[] = "GET / HTTP/1.1\r\n"
35342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Host: news.google.com\r\n"
35352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Connection: keep-alive\r\n\r\n";
35362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get2(
35377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
35382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char resp2[] = "HTTP/1.1 200 OK\r\n"
35392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Content-Length: 2\r\n\r\n";
35402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp2(
35417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
35422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body2(
35437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
35442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite spdy_writes[] = {
35462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*connect1, 0),
35472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*wrapped_get1, 2),
35482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*connect2, 5),
35492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*wrapped_get2, 7),
35502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
35512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead spdy_reads[] = {
35532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*conn_resp1, 1, ASYNC),
35542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
35552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_body1, 4, ASYNC),
35562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*conn_resp2, 6, ASYNC),
35572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
35582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_body2, 9, ASYNC),
35592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 0, 10),
35602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
35612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeterministicSocketData spdy_data(
35632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
35642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
35662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
35687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
35702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
35712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl2.was_npn_negotiated = false;
35722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl2.protocol_negotiated = kProtoUnknown;
3573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
35742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl3(ASYNC, OK);
35752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl3.was_npn_negotiated = false;
35762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl3.protocol_negotiated = kProtoUnknown;
3577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
35782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
35802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3582868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
35832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
35842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
35852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The first connect and request, each of their responses, and the body.
35862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(5);
35872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
35892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
35902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
35922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
35932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
35942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
35962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
3597868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
35982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
35992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string response_data;
36012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3602868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
36032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
3605868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
36062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
36072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
36082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The second connect and request, each of their responses, and the body.
36102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(5);
36112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
36122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
36132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
36152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
36162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Even though the SPDY connection is reused, a new tunnelled connection has
36172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to be created, so the socket's load timing looks like a fresh connection.
36182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
36192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The requests should have different IDs, since they each are using their own
36212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // separate stream.
36222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
36232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3624868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
36252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
36262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
36282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// HTTPS Proxy to the same server.
36297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
36302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
36312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against https proxy server "proxy:70".
3632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
36332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "https://proxy:70"));
36342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
3635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
36362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
3637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
36382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
36402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
36412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("https://www.google.com/");
36422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.load_flags = 0;
36432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
36452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
36462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("https://www.google.com/2");
36472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.load_flags = 0;
36482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY.
36503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
36513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                 LOWEST));
36527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp1(
36537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
36542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fetch https://www.google.com/ via HTTP.
36562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char get1[] = "GET / HTTP/1.1\r\n"
36572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Host: www.google.com\r\n"
36582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Connection: keep-alive\r\n\r\n";
36592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get1(
36607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
36612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char resp1[] = "HTTP/1.1 200 OK\r\n"
36622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Content-Length: 1\r\n\r\n";
36632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp1(
36647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
36657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body1(
36667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
36672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> window_update(
366890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
36692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fetch https://www.google.com/2 via HTTP.
36712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char get2[] = "GET /2 HTTP/1.1\r\n"
36722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Host: www.google.com\r\n"
36732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Connection: keep-alive\r\n\r\n";
36742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get2(
36757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
36762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char resp2[] = "HTTP/1.1 200 OK\r\n"
36772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Content-Length: 2\r\n\r\n";
36782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp2(
36797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
36802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body2(
36817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
36822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite spdy_writes[] = {
36842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*connect1, 0),
36852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*wrapped_get1, 2),
36862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*wrapped_get2, 5),
36872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
36882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead spdy_reads[] = {
36902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*conn_resp1, 1, ASYNC),
36912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
36922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_body1, 4, ASYNC),
36932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
36942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_body2, 7, ASYNC),
36952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 0, 8),
36962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
36972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeterministicSocketData spdy_data(
36992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
37002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
37022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
37047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
37062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
37072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl2.was_npn_negotiated = false;
37082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl2.protocol_negotiated = kProtoUnknown;
3709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
37102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
37122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3714868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
37152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
37162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
37172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The first connect and request, each of their responses, and the body.
37182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(5);
37192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
37212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
37222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
37242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
37252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
37262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
37282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
3729868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
37302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
37312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string response_data;
37332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3734868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
37352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans.reset();
37362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
3738868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
37392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
37402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
37412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The second request, response, and body.  There should not be a second
37432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // connect.
37442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(3);
37452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
37462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
37472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
37492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
37502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info2);
37512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The requests should have the same ID.
37532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
37542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3755868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
37562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
37572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
37592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Proxy to different servers.
37607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
37612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       HttpsProxySpdyLoadTimingTwoHttpRequests) {
37622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against https proxy server "proxy:70".
3763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
37642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "https://proxy:70"));
37652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
3766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
37672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
3768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
37692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
37712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
37722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("http://www.google.com/");
37732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.load_flags = 0;
37742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
37762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
37772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("http://news.google.com/");
37782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.load_flags = 0;
37792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // http://www.google.com/
37817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> headers(
37827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
3783116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<SpdyFrame> get1(
3784116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
37857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> get_resp1(
37867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
37877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(
37887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
37892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // http://news.google.com/
37917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> headers2(
37927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
3793116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<SpdyFrame> get2(
3794116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
37957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> get_resp2(
37967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
37977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(
37987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
37992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite spdy_writes[] = {
38012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*get1, 0),
38022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*get2, 3),
38032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
38042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead spdy_reads[] = {
38062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*get_resp1, 1, ASYNC),
38072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*body1, 2, ASYNC),
38082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*get_resp2, 4, ASYNC),
38092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*body2, 5, ASYNC),
38102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 0, 6),
38112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
38122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeterministicSocketData spdy_data(
38142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
38152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3816c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
38172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
38197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3820c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
38212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
38232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3825868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
38262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
38272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
38282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(2);
38292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
38312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
38322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
38342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
38352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
38362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
38372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
38392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
3840868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
38412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
38422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string response_data;
38442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3845868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
38462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(1);
38472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, callback.WaitForResult());
38482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Delete the first request, so the second one can reuse the socket.
38492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans.reset();
38502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
3852868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
38532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
38542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
38552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(2);
38572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
38582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
38592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
38612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
38622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info2);
38632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The requests should have the same ID.
38652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
38662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3867868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
38682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(1);
38692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, callback.WaitForResult());
38702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
38712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the challenge-response-retry sequence through an HTTPS Proxy
38737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
38745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
38755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
38765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
38775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the no authentication data flag is set.
38785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
38795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
3881c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
38825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://myproxy:70"));
38835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
38865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should use full url
38885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
38895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
38905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
38915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
38925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
38945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
38955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
38965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
38975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
38985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
38995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
39005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the GET with a 407, using a persistent
39025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
39035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
39045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No credentials.
39055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
39065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
39075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Connection: keep-alive\r\n"),
39085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
39095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
39115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
39125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
39135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
39145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
39155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
39175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
3918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
39195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
3920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
39215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
39235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3925868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
39265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
39285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
39295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
39315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
39325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
39342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
39352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
39362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
39372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
39395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
3940868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
39415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
39425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
39435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
39445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
39465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
39485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
39495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
39505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
39525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
39535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  load_timing_info = LoadTimingInfo();
39552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
39562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Retrying with HTTP AUTH is considered to be reusing a socket.
39572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info);
39582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
39605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
39615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
39635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
39645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
39655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
39665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
39685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
39695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
39705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
39725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockRead& status, int expected_status) {
39735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
39745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
39755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
39765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
39775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
3979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
3980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
39815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
39835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
39845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
39855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
39865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
39875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
39885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
39905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status,
39915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
39925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No response body because the test stops reading here.
39935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
39945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
39955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
39975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
3998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
39995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
40015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4003868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
40045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
40065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
40075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
40095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_status, rv);
40105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::ConnectStatusHelper(
40135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockRead& status) {
40145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelperWithExpectedStatus(
40155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      status, ERR_TUNNEL_CONNECTION_FAILED);
40165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
40195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
40205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
40235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
40245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
40275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
40285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
40315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
40325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
40355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(
40365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
40375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
40405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
40415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
40445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
40455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
40485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
40495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
40525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
40535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
40565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
40575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
40605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
40615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
40645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
40655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
40685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
40695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
40725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
40735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
40765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
40775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
40805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
40815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
40845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
40855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
40865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
40877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
40885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
40895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
40925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
40935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
40965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
40975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
41005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
41015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
41045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
41055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
41085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
41095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
41125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
41135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
41165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelperWithExpectedStatus(
41175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
41185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ERR_PROXY_AUTH_UNSUPPORTED);
41195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
41225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
41235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
41265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
41275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
41305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
41315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
41345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
41355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
41385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
41395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
41425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
41435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
41465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
41475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
41505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
41515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
41545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(
41555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
41565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
41595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
41605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
41635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
41645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
41675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
41685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
41715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
41725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
41755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
41765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
41795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
41805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
41835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
41845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the flow when both the proxy server AND origin server require
41875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// authentication. Again, this uses basic auth for both since that is
41885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the simplest to mock.
41897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
41905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
41915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
41925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
41935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
41945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Configure against proxy server "myproxy:70".
4196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
41978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
41985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
42001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
42015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
42035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
42045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
42055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
42065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
42095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 407 Unauthorized\r\n"),
42105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Give a couple authenticate options (only the middle one is actually
42115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // supported).
42125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic invalid\r\n"),  // Malformed.
42135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
42145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
42155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
42165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Large content-length -- won't matter, as connection will be reset.
42175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10000\r\n\r\n"),
42185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
42195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth() the first time, this is the
42225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // request we should be issuing -- the final header line contains the
42235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // proxy's credentials.
42245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
42255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
42265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
42275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
42285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
42295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now the proxy server lets the request pass through to origin server.
42325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The origin server responds with a 401.
42335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
42345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
42355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note: We are using the same realm-name as the proxy server. This is
42365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // completely valid, as realms are unique across hosts.
42375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
42385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
42395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 2000\r\n\r\n"),
42405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),  // Won't be reached.
42415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth() the second time, we should send
42445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the credentials for both the proxy and origin server.
42455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes3[] = {
42465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
42475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
42485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
42495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
42505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
42515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly we get the desired content.
42545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads3[] = {
42555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
42565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
42575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
42585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
42595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
42625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
42635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
42645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
42655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
42665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
4267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
4268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
4269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
42705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
42725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
42745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
42755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
42775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
42785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
42805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
42815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
42825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
42845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
42865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
42875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
42885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
42905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
42915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
42935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
42945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
42955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
42975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
42995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo2, kBar2), callback3.callback());
43005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
43015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
43035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
43045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
43065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
43075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
43085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
43095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For the NTLM implementation using SSPI, we skip the NTLM tests since we
43115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can't hook into its internals to cause it to generate predictable NTLM
43125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// authorization headers.
43135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NTLM_PORTABLE)
43145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The NTLM authentication unit tests were generated by capturing the HTTP
43155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// requests and responses using Fiddler 2 and inspecting the generated random
43165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bytes in the debugger.
43175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Enter the correct password and authenticate successfully.
43197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
43205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
43215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
43225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://172.22.68.17/kids/login.aspx");
43234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
43244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Ensure load is not disrupted by flags which suppress behaviour specific
43254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // to other auth schemes.
43264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
43275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
43295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    MockGetHostName);
4330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
43315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
43335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
43345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
43355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
43365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
43375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
43395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
43405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Negotiate and NTLM are often requested together.  However, we only want
43415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
43425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the header that requests Negotiate for this test.
43435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM\r\n"),
43445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: close\r\n"),
43455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
43465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
43475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Missing content -- won't matter, as connection will be reset.
43485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
43495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
43505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
43525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After restarting with a null identity, this is the
43535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // request we should be issuing -- the final header line contains a Type
43545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1 message.
43555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
43565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
43575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
43585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM "
43595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
43605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), we should send a Type 3 message
43625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (the credentials for the origin server).  The second request continues
43635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // on the same connection.
43645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
43655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
43665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
43675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
43685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
43695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
43705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
43715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "ahlhx5I=\r\n\r\n"),
43725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
43735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
43755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The origin server responds with a Type 2 message.
43765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
43775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM "
43785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
43795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
43805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
43815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
43825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
43835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
43845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "BtAAAAAAA=\r\n"),
43855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
43865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
43875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("You are not authorized to view this page\r\n"),
43885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly we get the desired content.
43905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
43915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=utf-8\r\n"),
43925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 13\r\n\r\n"),
43935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Please Login\r\n"),
43945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
43955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
43965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
43985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
43995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
44005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
4401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
4402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
44035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
44055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
44085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
44105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
44115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
44135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
44145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
44165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
44185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(response == NULL);
44195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
44205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
44225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
44245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              callback2.callback());
44255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
44265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
44285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
44295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
44315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
44335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
44345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
44355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
44375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
44395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
44405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
44425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
44435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
44455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
44465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
44475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(13, response->headers->GetContentLength());
44485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
44495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Enter a wrong password, and then the correct one.
44517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
44525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
44535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
44545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://172.22.68.17/kids/login.aspx");
44555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
44565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
44585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    MockGetHostName);
4459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
44605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
44625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
44635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
44645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
44655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
44665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
44685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
44695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Negotiate and NTLM are often requested together.  However, we only want
44705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
44715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the header that requests Negotiate for this test.
44725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM\r\n"),
44735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: close\r\n"),
44745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
44755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
44765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Missing content -- won't matter, as connection will be reset.
44775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
44785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
44795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
44815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After restarting with a null identity, this is the
44825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // request we should be issuing -- the final header line contains a Type
44835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1 message.
44845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
44855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
44865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
44875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM "
44885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
44895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), we should send a Type 3 message
44915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (the credentials for the origin server).  The second request continues
44925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // on the same connection.
44935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
44945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
44955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
44965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
44975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
44985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
44995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
45005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "4Ww7b7E=\r\n\r\n"),
45015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
45025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
45045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The origin server responds with a Type 2 message.
45055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
45065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM "
45075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
45085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
45095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
45105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
45115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
45125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
45135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "BtAAAAAAA=\r\n"),
45145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
45155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
45165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("You are not authorized to view this page\r\n"),
45175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Wrong password.
45195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
45205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM\r\n"),
45215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: close\r\n"),
45225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
45235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
45245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Missing content -- won't matter, as connection will be reset.
45255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
45265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
45275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes3[] = {
45295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After restarting with a null identity, this is the
45305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // request we should be issuing -- the final header line contains a Type
45315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1 message.
45325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
45335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
45345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
45355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM "
45365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
45375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), we should send a Type 3 message
45395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (the credentials for the origin server).  The second request continues
45405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // on the same connection.
45415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
45425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
45435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
45445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
45455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
45465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
45475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
45485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "+4MUm7c=\r\n\r\n"),
45495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
45505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads3[] = {
45525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The origin server responds with a Type 2 message.
45535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
45545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM "
45555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
45565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
45575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
45585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
45595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
45605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
45615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "BtAAAAAAA=\r\n"),
45625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
45635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
45645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("You are not authorized to view this page\r\n"),
45655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly we get the desired content.
45675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
45685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=utf-8\r\n"),
45695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 13\r\n\r\n"),
45705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Please Login\r\n"),
45715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
45725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
45735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
45755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
45765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
45775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
45785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
45795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
4580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
4581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
4582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
45835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
45855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4587868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
45885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
45905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
45915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
45935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
45945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
45965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
45985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
45995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
46005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
46025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enter the wrong password.
46045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
46055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              callback2.callback());
46065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
46075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
46095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
46105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
46125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
46135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
46145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
46155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
46165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
46175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
46185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
46205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(response == NULL);
46215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
46225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback4;
46245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now enter the right password.
46265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
46275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              callback4.callback());
46285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
46295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback4.WaitForResult();
46315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
46325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
46345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback5;
46365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // One more roundtrip
46385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
46395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
46405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback5.WaitForResult();
46425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
46435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
46455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
46465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(13, response->headers->GetContentLength());
46475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
46485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // NTLM_PORTABLE
46495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test reading a server response which has only headers, and no body.
46515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// After some maximum number of bytes is consumed, the transaction should
46525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
46537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
46545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
46555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
46565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
46575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
46585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
46605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
46611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
46625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Respond with 300 kb of headers (we should fail after 256 kb).
46645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string large_headers_string;
46655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FillLargeHeadersString(&large_headers_string, 300 * 1024);
46665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
46685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
46695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
46705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\r\nBODY"),
46715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
46725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
46735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
46755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
46775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
46795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
46805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
46825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
46835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
46855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response == NULL);
46865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
46875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that we don't try to reuse a TCPClientSocket when failing to
46895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// establish tunnel.
46905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/chromium/issues/detail?id=3772
46917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
46925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       DontRecycleTransportSocketForSSLTunnel) {
46935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
46945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
46955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
46965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
46975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
4699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
47005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
47025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4704868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
47055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
47075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
47085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
47095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
47105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
47115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 404, using a persistent
47145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection. Usually a proxy would return 501 (not implemented),
47155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or 200 (tunnel established).
47165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
47175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 404 Not Found\r\n"),
47185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
47195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
47205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
47235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
4724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
47255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
47275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
47295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
47305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
47325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
47335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
47355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response == NULL);
47365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
47385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
473990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
47405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the TCPClientSocket was not added back to
47425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the pool.
4743868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
47445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
474590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
47465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure that the socket didn't get recycled after calling the destructor.
4747868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
47485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
47495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that we recycle a socket after reading all of the response body.
47517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
47525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
47535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
47545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
47555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
47565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
47585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4760868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
47615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
47635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // A part of the response body is received with the response headers.
47645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
47655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The rest of the response body is received in two parts.
47665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("lo"),
47675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(" world"),
47685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("junk"),  // Should not be read!!
47695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
47705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
47745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
47765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
47785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
47795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
47815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
47825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
47845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
47855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4786868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
47875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string status_line = response->headers->GetStatusLine();
47885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", status_line);
47895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4790868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
47915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
47935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
47945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
47955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
47965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
47985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
479990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
48005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4802868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
48035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
48045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that we recycle a SSL socket after reading all of the response
48065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// body.
48077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
48085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
48095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
48105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
48115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
48125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
48145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
48155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
48165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
48175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
48185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
48205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
48215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 11\r\n\r\n"),
48225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
48235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
48245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
48255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
4827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
48285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
48305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
4831c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
48325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
48345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4835c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
48362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4837868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
48385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
48405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
48425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
48435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
48455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
4846868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
48475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
48485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4849868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
48505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
48525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
48535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
48545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
48555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
48575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
485890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
48595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4861868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
48625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
48635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Grab a SSL socket, use it, and put it back into the pool.  Then, reuse it
48655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from the pool and make sure that we recover okay.
48667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
48675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
48685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
48695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
48705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
48715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
48735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
48745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
48755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
48765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
48775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
48785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
48795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
48805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
48825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
48835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 11\r\n\r\n"),
48845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
48855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
48865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0)   // EOF
48875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
48885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
48905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
4891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
48935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
48955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
48965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
48975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
4898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
4899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
49005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
49025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4903c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
49042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4905868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
49065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
49085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
49105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
49115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
49135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
4914868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
49155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
49165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4917868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
49185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
49205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
49215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
49225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
49235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
49255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
492690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
49275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4929868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
49305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now start the second transaction, which should reuse the previous socket.
49325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4933868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
49345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
49365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
49385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
49395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
49415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
4942868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
49435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
49445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4945868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
49465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
49485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
49495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
49505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
49525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
495390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
49545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4956868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
49575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
49585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that we recycle a socket after a zero-length response.
49605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/9880
49617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
49625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
49635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
49645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
49655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
49665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     "e=17259,18167,19592,19773,19981,20133,20173,20233&"
49675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     "rt=prt.2642,ol.2649,xjs.2951");
49685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
49695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
49715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4973868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
49745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
49765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 204 No Content\r\n"
49775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 0\r\n"
49785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Type: text/html\r\n\r\n"),
49795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("junk"),  // Should not be read!!
49805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
49815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
49825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
49855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
49875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
49895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
49905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
49925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
49935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
49955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
49965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4997868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
49985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string status_line = response->headers->GetStatusLine();
49995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
50005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5001868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
50025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
50045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
50055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
50065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", response_data);
50075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
50095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
501090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
50115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
5013868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
50145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
50155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
50172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
50182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(new UploadBytesElementReader("foo", 3));
501968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
50202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
50215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request[2];
50225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 1: a GET request that succeeds.  The socket is recycled
50235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // after use.
50245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[0].method = "GET";
50255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[0].url = GURL("http://www.google.com/");
50265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[0].load_flags = 0;
50275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 2: a POST request.  Reuses the socket kept alive from
50285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction 1.  The first attempts fails when writing the POST data.
50295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This causes the transaction to retry with a new socket.  The second
50305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // attempt succeeds.
50315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[1].method = "POST";
50325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[1].url = GURL("http://www.google.com/login.cgi");
50332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request[1].upload_data_stream = &upload_data_stream;
50345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[1].load_flags = 0;
50355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5036c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
50375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first socket is used for transaction 1 and the first attempt of
50395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction 2.
50405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The response of transaction 1.
50425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
50435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
50445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
50455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
50465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
50475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The mock write results of transaction 1 and the first attempt of
50485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction 2.
50495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
50505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 64),  // GET
50515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 93),  // POST
50525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED),  // POST data
50535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
50545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
50555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
50565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The second socket is used for the second attempt of transaction 2.
50585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The response of transaction 2.
50605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
50615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
50625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("welcome"),
50635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
50645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
50655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The mock write results of the second attempt of transaction 2.
50665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
50675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 93),  // POST
50685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 3),  // POST data
50695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
50705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
50715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
50725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5073c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
5074c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
50755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kExpectedResponseData[] = {
50775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "hello world", "welcome"
50785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
50795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; ++i) {
50815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5082868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
50835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
50855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
50875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
50885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
50905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
50915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
50935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
50945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response->headers.get() != NULL);
50965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
50975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string response_data;
50995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ReadTransaction(trans.get(), &response_data);
51005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
51015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kExpectedResponseData[i], response_data);
51025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
51035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
51045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth when there is
51065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// an identity in the URL. The request should be sent as normal, but when
51075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it fails the identity from the URL is used to answer the challenge.
51087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
51095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
51105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
51115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://foo:b@r@www.google.com/");
51125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = LOAD_NORMAL;
51135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
51155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
51161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
51175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password contains an escaped character -- for this test to pass it
51195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will need to be unescaped by HttpNetworkTransaction.
51205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("b%40r", request.url.password());
51215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
51235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
51245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
51255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
51265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
51275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
51295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
51305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
51315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
51325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
51335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
51345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the challenge above, the transaction will be restarted using the
51365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // identity from the url (foo, b@r) to answer the challenge.
51375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
51385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
51395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
51405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
51415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
51425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
51435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
51455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
51465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
51475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
51485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
51495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
51515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
51525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
51535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
5154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
5155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
51565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
51585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
51595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
51605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
51615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
51625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
51635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
51655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
51665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
51675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
51685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
51695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
51705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
51725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
51735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There is no challenge info, since the identity in URL worked.
51755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
51765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
51785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.
518090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
51815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
51825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth when there is an
51845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// incorrect identity in the URL. The identity from the URL should be used only
51855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// once.
51867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
51875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
51885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
51895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: the URL has a username:password in it.  The password "baz" is
51905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // wrong (should be "bar").
51915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://foo:baz@www.google.com/");
51925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = LOAD_NORMAL;
51945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
51965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
51971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
51985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
52005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
52015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
52025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
52035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
52045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
52065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
52075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
52085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
52095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
52105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
52115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the challenge above, the transaction will be restarted using the
52135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // identity from the url (foo, baz) to answer the challenge.
52145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
52155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
52165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
52175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
52185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
52195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
52205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
52225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
52235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
52245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
52255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
52265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
52275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the challenge above, the transaction will be restarted using the
52295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // identity supplied by the user (foo, bar) to answer the challenge.
52305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes3[] = {
52315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
52325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
52335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
52345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
52355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
52365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads3[] = {
52385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
52395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
52405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
52415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
52425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
52445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
52455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
52465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
52475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
52485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
5249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
5250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
5251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
52525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
52545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
52565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
52575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
52595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
52605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
52625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
52635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
52645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
52655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
52665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
52675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
52685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
52705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
52715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
52725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
52745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
52755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback3.callback());
52765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
52775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
52785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
52795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
52805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
52825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
52835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There is no challenge info, since the identity worked.
52855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
52865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
52885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.
529090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
52915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
52925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
52944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Test the request-challenge-retry sequence for basic auth when there is a
52954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// correct identity in the URL, but its use is being suppressed. The identity
52964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// from the URL should never be used.
52974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
52984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  HttpRequestInfo request;
52994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.method = "GET";
53004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.url = GURL("http://foo:bar@www.google.com/");
53014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
53024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
53044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
53051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
53064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MockWrite data_writes1[] = {
53084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
53094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Host: www.google.com\r\n"
53104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
53114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
53124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MockRead data_reads1[] = {
53144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
53154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
53164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
53174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
53184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
53194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // After the challenge above, the transaction will be restarted using the
53214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // identity supplied by the user, not the one in the URL, to answer the
53224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // challenge.
53234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MockWrite data_writes3[] = {
53244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
53254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Host: www.google.com\r\n"
53264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Connection: keep-alive\r\n"
53274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
53284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
53294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MockRead data_reads3[] = {
53314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
53324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
53334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
53344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
53354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
53374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
53384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
53394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
53404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
53414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
53424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestCompletionCallback callback1;
53444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
53454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
53464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  rv = callback1.WaitForResult();
53474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(OK, rv);
53484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
53494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
53514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
53524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
53534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestCompletionCallback callback3;
53554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  rv = trans->RestartWithAuth(
53564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      AuthCredentials(kFoo, kBar), callback3.callback());
53574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
53584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  rv = callback3.WaitForResult();
53594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(OK, rv);
53604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
53614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  response = trans->GetResponseInfo();
53634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
53644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // There is no challenge info, since the identity worked.
53664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
53674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
53684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Empty the current queue.
53704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
53714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
53724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that previously tried username/passwords for a realm get re-used.
53747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
5375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
53765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 1: authenticate (foo, bar) on MyRealm1
53785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
53795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
53805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
53815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/z");
53825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
53835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
53865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
53885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z HTTP/1.1\r\n"
53895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
53905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n\r\n"),
53915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
53925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
53945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
53955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
53965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
53975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
53985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
53995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization (username=foo, password=bar)
54015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
54025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z HTTP/1.1\r\n"
54035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
54045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
54055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
54065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
54075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
54095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
54105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
54115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
54125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
54135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
54145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
54165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
54175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
54185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
5419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
54215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
54235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
54255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
54265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
54285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
54295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
54315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
54325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
54335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
54355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(
54375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AuthCredentials(kFoo, kBar), callback2.callback());
54385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
54395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
54415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
54425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response = trans->GetResponseInfo();
54445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
54455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
54465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
54475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
54485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
54505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 2: authenticate (foo2, bar2) on MyRealm2
54525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
54535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
54545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
54555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note that Transaction 1 was at /x/y/z, so this is in the same
54565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // protection space as MyRealm1.
54575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/a/b");
54585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
54595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5461868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
54625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
54645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
54655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
54665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
54675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // Send preemptive authorization for MyRealm1
54685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
54695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
54705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The server didn't like the preemptive authorization, and
54725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // challenges us for a different realm (MyRealm2).
54735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
54745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
54755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
54765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
54775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
54785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
54795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
54815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
54825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
54835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
54845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
54855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
54865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
54875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
54895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
54905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
54915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
54925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
54935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
54945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
54965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
54975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
54985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
5499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
55015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
55035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
55055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
55065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
55085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
55095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
55115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
55125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response->auth_challenge.get());
55135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(response->auth_challenge->is_proxy);
55145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("www.google.com:80",
55155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              response->auth_challenge->challenger.ToString());
55165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
55175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("basic", response->auth_challenge->scheme);
55185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
55205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(
55225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AuthCredentials(kFoo2, kBar2), callback2.callback());
55235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
55245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
55265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
55275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response = trans->GetResponseInfo();
55295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
55305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
55315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
55325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
55335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
55355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 3: Resend a request in MyRealm's protection space --
55375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // succeed with preemptive authorization.
55385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
55395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
55405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
55415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/z2");
55425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
55435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
55465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
55485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
55495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
55505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
55515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // The authorization for MyRealm1 gets sent preemptively
55525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // (since the url is in the same protection space)
55535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
55545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
55555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the preemptive authorization
55575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
55585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
55595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
55605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
55615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
55625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
55645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
5565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
55665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
55685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
55705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
55715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
55735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
55745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
55765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
55775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
55795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
55805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
55815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
55835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 4: request another URL in MyRealm (however the
55855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // url is not known to belong to the protection space, so no pre-auth).
55865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
55875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
55885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
55895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/1");
55905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
55915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5593868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
55945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
55965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/1 HTTP/1.1\r\n"
55975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
55985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n\r\n"),
55995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
56025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
56035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
56045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
56055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
56065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization from MyRealm's cache.
56095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
56105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/1 HTTP/1.1\r\n"
56115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
56125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
56135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
56145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
56175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
56185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
56195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
56205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
56215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
56245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
56255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
56265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
5627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
56295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
56315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
56335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
56345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
56365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
56375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(trans->IsReadyToRestartForAuth());
56395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
56405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
56415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
56425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
56435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
56445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(trans->IsReadyToRestartForAuth());
56455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
56475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
56485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
56495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
56505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
56515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
56535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 5: request a URL in MyRealm, but the server rejects the
56555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cached identity. Should invalidate and re-prompt.
56565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
56575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
56585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
56595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/p/q/t");
56605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
56615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5663868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
56645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
56665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /p/q/t HTTP/1.1\r\n"
56675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
56685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n\r\n"),
56695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
56725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
56735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
56745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
56755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
56765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization from cache for MyRealm.
56795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
56805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /p/q/t HTTP/1.1\r\n"
56815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
56825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
56835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
56845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever rejects the authorization.
56875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
56885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
56895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
56905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
56915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
56925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // At this point we should prompt for new credentials for MyRealm.
56955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Restart with username=foo3, password=foo4.
56965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes3[] = {
56975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /p/q/t HTTP/1.1\r\n"
56985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
56995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
57005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
57015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
57025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
57045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads3[] = {
57055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
57065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
57075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
57085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
57095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
57115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
57125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
57135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
57145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
57155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes3, arraysize(data_writes3));
5716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
5718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data3);
57195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
57215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
57235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
57245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
57265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
57275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(trans->IsReadyToRestartForAuth());
57295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
57305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
57315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
57325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
57335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
57345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(trans->IsReadyToRestartForAuth());
57355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
57375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
57385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
57395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback3;
57415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(
57435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AuthCredentials(kFoo3, kBar3), callback3.callback());
57445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
57455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback3.WaitForResult();
57475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
57485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response = trans->GetResponseInfo();
57505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
57515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
57525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
57535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
57545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
57555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that nonce count increments when multiple auth attempts
57575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are started with the same nonce.
57587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
57595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerDigest::Factory* digest_factory =
57605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new HttpAuthHandlerDigest::Factory();
57615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
57625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
57635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  digest_factory->set_nonce_generator(nonce_generator);
5764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.http_auth_handler_factory.reset(digest_factory);
5765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
57665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 1: authenticate (foo, bar) on MyRealm1
57685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
57695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
57705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
57715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/z");
57725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
57735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5775868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
57765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
57785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z HTTP/1.1\r\n"
57795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
57805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n\r\n"),
57815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
57825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
57845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
57855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
57865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
57875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
57885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
57895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization (username=foo, password=bar)
57915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
57925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z HTTP/1.1\r\n"
57935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
57945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
57955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Digest username=\"foo\", realm=\"digestive\", "
57965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
57975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
57985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
57995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
58005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
58025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
58035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
58045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
58055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
58065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
58085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
58095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
58105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
5811c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5812c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
58135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
58155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
58175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
58185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
58205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
58215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
58235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
58245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
58255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
58275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(
58295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AuthCredentials(kFoo, kBar), callback2.callback());
58305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
58315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
58335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
58345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response = trans->GetResponseInfo();
58365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
58375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
58385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
58395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
58415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 2: Request another resource in digestive's protection space.
58435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This will preemptively add an Authorization header which should have an
58445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "nc" value of 2 (as compared to 1 in the first use.
58455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
58465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
58475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
58485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note that Transaction 1 was at /x/y/z, so this is in the same
58495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // protection space as digest.
58505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/a/b");
58515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
58525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5854868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
58555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
58575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
58585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
58595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
58605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Digest username=\"foo\", realm=\"digestive\", "
58615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
58625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
58635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
58645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
58655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
58675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
58685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
58695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
58705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
58715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
58725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
58745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
5875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
58765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
58785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
58805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
58815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
58835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
58845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
58865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
58875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
58885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
58895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
58905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the ResetStateForRestart() private method.
58927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
58935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a transaction (the dependencies aren't important).
58948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
58955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans(
58961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
58975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setup some state (which we expect ResetStateForRestart() will clear).
58995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans->read_buf_ = new IOBuffer(15);
59005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans->read_buf_len_ = 15;
59015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans->request_headers_.SetHeader("Authorization", "NTLM");
59025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setup state in response_
59045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpResponseInfo* response = &trans->response_;
59055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->auth_challenge = new AuthChallengeInfo();
59065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->ssl_info.cert_status = static_cast<CertStatus>(-1);  // Nonsensical.
59075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->response_time = base::Time::Now();
59085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->was_cached = true;  // (Wouldn't ever actually be true...)
59095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { // Setup state for response_.vary_data
59115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
59125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
59135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::replace(temp.begin(), temp.end(), '\n', '\0');
59145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
59155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.extra_headers.SetHeader("Foo", "1");
59165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.extra_headers.SetHeader("bar", "23");
5917868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
59185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
59195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cause the above state to be reset.
59215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans->ResetStateForRestart();
59225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the state that needed to be reset, has been reset.
59245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->read_buf_.get() == NULL);
59255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, trans->read_buf_len_);
59265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->request_headers_.IsEmpty());
59275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
59285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() == NULL);
59295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_cached);
59305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, response->ssl_info.cert_status);
59315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->vary_data.is_valid());
59325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
59335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections to a site with a bad certificate
59357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
59365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
59375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
59385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
59395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
59405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
59425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
59431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
59445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
59465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
59475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
59485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
59495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
59505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
59525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
59535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
59545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
59555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
59565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
59575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider ssl_bad_certificate;
59595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
59605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
59615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
59625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
59635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
5966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
59685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
59705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
59725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
59735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
59755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
59765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartIgnoringLastError(callback.callback());
59785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
59795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
59815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
59825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
59845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
59865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
59875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
59885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections to a site with a bad certificate, going through a
59905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// proxy
59917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
5992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
59935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
59955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
59965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
59975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
59985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite proxy_writes[] = {
60005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
60015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
60025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
60035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
60045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead proxy_reads[] = {
60065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
60075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
60085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
60095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
60115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
60125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
60135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
60145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
60155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
60165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
60175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
60185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
60205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
60215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
60225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
60235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
60245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
60255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
60265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider ssl_bad_certificate(
60285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      proxy_reads, arraysize(proxy_reads),
60295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      proxy_writes, arraysize(proxy_writes));
60305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
60315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
60325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
60335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
60345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6036c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6037c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
60395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
60415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; i++) {
6043c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->ResetNextMockIndexes();
60445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
60465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
60471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
60485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
60505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
60515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
60535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
60545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartIgnoringLastError(callback.callback());
60565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
60575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
60595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
60605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
60625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
60645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
60655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
60665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
60675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections to a site, going through an HTTPS proxy
60707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
6071c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
60722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
60732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
6074c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
60755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
60775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
60785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
60795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
60805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
60825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
60835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
60845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
60855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
60865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
60875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
60885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
60895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
60915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
60925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
60935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
60945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
60955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
60965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
60975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
60995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
61005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
61015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider tunnel_ssl(ASYNC, OK);  // SSL through the tunnel
61025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
61065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
61085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
61105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
61111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
61125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
61145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
61155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
61175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
61185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
61195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
61215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
61235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
61245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
61255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
61262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
61272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
61282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
61292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
61302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
61315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
61325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test an HTTPS Proxy's ability to redirect a CONNECT request
61347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
6135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
61362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
61372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
6138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
61395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
61415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
61425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
61435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
61445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
61465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
61475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
61485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
61495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
61505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
61525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Redirect\r\n"),
61535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://login.example.com/\r\n"),
61545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
61555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
61565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
61575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
61595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
61605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
61615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
61645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
61665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
61685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
61691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
61705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
61725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
61735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
61755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
61765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
61775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
61795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(302, response->headers->response_code());
61815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
61825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsRedirect(&url));
61835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://login.example.com/", url);
61842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
61852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // In the case of redirects from proxies, HttpNetworkTransaction returns
61862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // timing for the proxy connection instead of the connection to the host,
61872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // and no send / receive times.
61882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
61892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
61902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
61912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
61922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.socket_reused);
61932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
61942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
61952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
61962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_start,
61972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.proxy_resolve_end);
61982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_end,
61992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.connect_timing.connect_start);
62002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectConnectTimingHasTimes(
62012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      load_timing_info.connect_timing,
62022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
62032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
62042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.send_start.is_null());
62052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.send_end.is_null());
62062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
62075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
62085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
62107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
6211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
62125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://proxy:70"));
62135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
62155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
62165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
62175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
62185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
62203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                             LOWEST));
622190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> goaway(
622290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
62235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
62245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
6225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
62265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* const kExtraHeaders[] = {
62295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "location",
62305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "http://login.example.com/",
62315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(
62337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
62345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 arraysize(kExtraHeaders)/2, 1));
62355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
62365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
62375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 2),  // EOF
62385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data(
62415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
62425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads),
62435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_writes, arraysize(data_writes));
62445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
62457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy_ssl.SetNextProto(GetParam());
62465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
62495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
62515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
62535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
62541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
62555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
62575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
62585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
62605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
62615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
62625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
62645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(302, response->headers->response_code());
62665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
62675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsRedirect(&url));
62685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://login.example.com/", url);
62695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
62705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that an HTTPS proxy's response to a CONNECT request is filtered.
62727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
62735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ErrorResponseToHttpsConnectViaHttpsProxy) {
6274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
62755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://proxy:70"));
62765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
62785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
62795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
62805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
62815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
62835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
62845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
62855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
62865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
62895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 404 Not Found\r\n"),
62905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 23\r\n\r\n"),
62915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("The host does not exist"),
62925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
62935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
62965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
62975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
62985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
63015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
63035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
63055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
63061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
63075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
63095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
63105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
63125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
63135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(ttuttle): Anything else to check here?
63155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
63165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that a SPDY proxy's response to a CONNECT request is filtered.
63187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
63195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ErrorResponseToHttpsConnectViaSpdyProxy) {
6320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
6321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     ProxyService::CreateFixed("https://proxy:70"));
63225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
63245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
63255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
63265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
63275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
63293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                             LOWEST));
633090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> rst(
633190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
63325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
63335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
63345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
63355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
63365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* const kExtraHeaders[] = {
63385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "location",
63395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "http://login.example.com/",
63405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
63415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(
63427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
63435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 arraysize(kExtraHeaders)/2, 1));
63445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> body(
63457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(
63467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          1, "The host does not exist", 23, true));
63475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
63485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
63495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body.get(), 2, SYNCHRONOUS),
63505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 4),  // EOF
63515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
63525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data(
63545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
63555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads),
63565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_writes, arraysize(data_writes));
63575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
63587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy_ssl.SetNextProto(GetParam());
63595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
63625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
63645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
63665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
63671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
63685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
63705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
63715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
63735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
63745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(ttuttle): Anything else to check here?
63765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
63775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, through
63795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a SPDY proxy over a single SPDY session.
63807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
63815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
63825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
63835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
63845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the no authentication data flag is set.
63855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
63865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
6388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
63892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
63905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
6391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
6392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
63935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
63953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
63963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                            LOWEST));
639790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> rst(
639890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
63995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), this is the request we should
64015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be issuing -- the final header line contains the credentials.
64025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kAuthCredentials[] = {
64035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "proxy-authorization", "Basic Zm9vOmJhcg==",
64045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
640590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
64063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
64075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetch https://www.google.com/ via HTTP
64085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char get[] = "GET / HTTP/1.1\r\n"
64095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Host: www.google.com\r\n"
64105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Connection: keep-alive\r\n\r\n";
64115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get(
64127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
64135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
64155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req, 1, ASYNC),
64165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*rst, 4, ASYNC),
64175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*connect2, 5),
64185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*wrapped_get, 8),
64195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
64205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
64225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
6423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const char* const kAuthStatus = "407";
64245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kAuthChallenge[] = {
64255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "proxy-authenticate", "Basic realm=\"MyRealm1\"",
64265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6428116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
64295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp(
64317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
64325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char resp[] = "HTTP/1.1 200 OK\r\n"
64335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 5\r\n\r\n";
64345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp(
64367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
64375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body(
64387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
64395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
64405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_auth_resp, 2, ASYNC),
64415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_resp, 6, ASYNC),
64425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_get_resp, 9, ASYNC),
64435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body, 10, ASYNC),
64445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK, 11),  // EOF.  May or may not be read.
64455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
64465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
64485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
64495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
6450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
64515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Negotiate SPDY to the proxy
64525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy(ASYNC, OK);
64537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy.SetNextProto(GetParam());
6454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
64555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Vanilla SSL to the server
64565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider server(ASYNC, OK);
6457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
64585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
64605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
6462868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
64635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
64655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
64665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
64685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
64695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
64705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
64715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
64725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
64735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
64745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
64755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
64765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
64775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
64785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
64805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
6481868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
64825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
64835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
64845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() != NULL);
64855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
64865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
64885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
64905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              callback2.callback());
64915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
64925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
64945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
64955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
64975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
64985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
65005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
65015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
65025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
65035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
65055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
65065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
65082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
65092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
65102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
65112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
65125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
65135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
65145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
65155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that an explicitly trusted SPDY proxy can push a resource from an
65175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// origin that is different from that of its associated resource.
65187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
65195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
65205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo push_request;
65215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
65235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
65245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  push_request.method = "GET";
65255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  push_request.url = GURL("http://www.another-origin.com/foo.dat");
65265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
6528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
65292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
65305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
6531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
65325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable cross-origin push.
6534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.trusted_spdy_proxy = "myproxy:70";
65355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
65375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
653890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> stream1_syn(
653990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
65405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
654290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CreateMockWrite(*stream1_syn, 1, ASYNC),
65435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
65445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
65467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
65475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
65497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
65505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
65527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
65535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    0,
65545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    2,
65555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    1,
65565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    "http://www.another-origin.com/foo.dat"));
6557eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const char kPushedData[] = "pushed";
6558eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<SpdyFrame> stream2_body(
6559eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      spdy_util_.ConstructSpdyBodyFrame(
6560eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          2, kPushedData, strlen(kPushedData), true));
65615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
65635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream1_reply, 2, ASYNC),
65645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream2_syn, 3, ASYNC),
65655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream1_body, 4, ASYNC),
6566eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    CreateMockRead(*stream2_body, 5, ASYNC),
65675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
65685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
65695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
65715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
65725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
6573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
65745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Negotiate SPDY to the proxy
65755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy(ASYNC, OK);
65767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy.SetNextProto(GetParam());
6577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
65785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
6580868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
65815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
65825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), log.bound());
65835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
65845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
65865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
65875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
65885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> push_trans(
6590868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = push_trans->Start(&push_request, callback.callback(), log.bound());
65925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
65935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
65955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
65965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
65975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
65995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
66005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
66025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
66035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
66055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
66065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
66075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
66085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
66102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
66112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
66122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
66132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
66145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify the pushed stream.
6615868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(push_response->headers.get() != NULL);
66165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, push_response->headers->response_code());
66175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(push_trans.get(), &response_data);
66195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
66205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("pushed", response_data);
66215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo push_load_timing_info;
66232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
66242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReusedWithPac(push_load_timing_info);
66252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The transactions should share a socket ID, despite being for different
66262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // origins.
66272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info.socket_log_id,
66282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            push_load_timing_info.socket_log_id);
66292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
66305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
66315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  push_trans.reset();
66325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
66335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
66345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
66367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
66375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
66385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
66405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
66415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
6643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
66445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://myproxy:70"));
66455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
6646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
66475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable cross-origin push.
6649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.trusted_spdy_proxy = "myproxy:70";
66505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
66525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> stream1_syn(
665490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
66555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> push_rst(
665790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
66585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
66605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*stream1_syn, 1, ASYNC),
66615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*push_rst, 4),
66625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
66635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
66657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
66665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
66687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
66695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
66717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
66725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    0,
66735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    2,
66745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    1,
66755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    "https://www.another-origin.com/foo.dat"));
66765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
66785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream1_reply, 2, ASYNC),
66795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream2_syn, 3, ASYNC),
66805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream1_body, 5, ASYNC),
66815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
66825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
66835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
66855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
66865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
6687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
66885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Negotiate SPDY to the proxy
66895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy(ASYNC, OK);
66907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy.SetNextProto(GetParam());
6691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
66925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
6694868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
66955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
66965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), log.bound());
66975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
66985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
67005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
67015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
67025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
67045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
67055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
67075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
67085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
67105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
67115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
67125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
67135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
67155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
67165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
67175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections to a site with a bad certificate, going through an
67195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HTTPS proxy
67207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
6721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
67225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
67235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
67255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
67265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
67275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
67285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attempt to fetch the URL from a server with a bad cert
67305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite bad_cert_writes[] = {
67315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
67325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
67335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
67345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
67355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead bad_cert_reads[] = {
67375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
67385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
67395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
67405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attempt to fetch the URL with a good cert
67425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite good_data_writes[] = {
67435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
67445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
67455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
67465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
67475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
67485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
67495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
67505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead good_cert_reads[] = {
67525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
67535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
67545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
67555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
67565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
67575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
67585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider ssl_bad_certificate(
67605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bad_cert_reads, arraysize(bad_cert_reads),
67615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bad_cert_writes, arraysize(bad_cert_writes));
67625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
67635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                good_data_writes, arraysize(good_data_writes));
67645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
67655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
67665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SSL to the proxy, then CONNECT request, then SSL with bad certificate
6768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
67715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SSL to the proxy, then CONNECT request, then valid SSL certificate
6773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
67765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
67785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
67805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
67811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
67825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
67845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
67855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
67875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
67885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartIgnoringLastError(callback.callback());
67905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
67915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
67935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
67945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
67965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
67985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
67995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
68005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
68025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
68035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
68045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
68055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
68065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  "Chromium Ultra Awesome X Edition");
68075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
68095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
68101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
68115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
68135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
68145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
68155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
68165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
68175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
68205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
68215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
68225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
68235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
68245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
68255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
68285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
68305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
68325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
68345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
68355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
68375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
68385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
68395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
68415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
68425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
68435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
68445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
68455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  "Chromium Ultra Awesome X Edition");
68465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
68488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
68495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
68501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
68515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
68535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
68545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
68555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
68565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
68575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
68595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return an error, so the transaction stops here (this test isn't
68605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // interested in the rest).
68615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
68625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
68635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Connection: close\r\n\r\n"),
68645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
68675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
68695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
68715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
68735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
68745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
68765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
68775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
68785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
68805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
68815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
68825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
68835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
68845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
68855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  "http://the.previous.site.com/");
68865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
68885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
68891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
68905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
68925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
68935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
68945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
68955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Referer: http://the.previous.site.com/\r\n\r\n"),
68965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
68995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
69005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
69015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
69025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
69035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
69045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
69075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
69095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
69115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
69135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
69145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
69165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
69175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
69185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
69205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
69215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
69225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
69235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
69255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
69261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
69275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
69295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("POST / HTTP/1.1\r\n"
69305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
69315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
69325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
69335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
69365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
69375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
69385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
69395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
69405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
69415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
69445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
69465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
69485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
69505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
69515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
69535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
69545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
69555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
69575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
69585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "PUT";
69595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
69605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
69625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
69631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
69645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
69665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("PUT / HTTP/1.1\r\n"
69675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
69685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
69695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
69705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
69735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
69745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
69755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
69765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
69775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
69785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
69815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
69835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
69855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
69875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
69885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
69905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
69915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
69925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
69945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
69955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "HEAD";
69965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
69975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
69995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
70001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
70015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
70035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("HEAD / HTTP/1.1\r\n"
70045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
70055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
70065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
70075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
70085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
70105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
70115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
70125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
70135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
70145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
70155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
70165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
70185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7019c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
70205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
70225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
70245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
70255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
70275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
70285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
70295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
70315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
70325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
70335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
70345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = LOAD_BYPASS_CACHE;
70355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
70375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
70381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
70395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
70415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
70425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
70435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
70445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Pragma: no-cache\r\n"
70455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Cache-Control: no-cache\r\n\r\n"),
70465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
70475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
70495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
70505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
70515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
70525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
70535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
70545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
70555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
70575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7058c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
70595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
70615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
70635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
70645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
70665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
70675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
70685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
70705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       BuildRequest_CacheControlValidateCache) {
70715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
70725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
70735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
70745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = LOAD_VALIDATE_CACHE;
70755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
70775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
70781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
70795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
70815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
70825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
70835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
70845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Cache-Control: max-age=0\r\n\r\n"),
70855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
70865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
70885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
70895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
70905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
70915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
70925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
70935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
70945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
70965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7097c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
70985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
71005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
71025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
71035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
71055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
71065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
71075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
71095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
71105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
71115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
71125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader("FooHeader", "Bar");
71135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
71155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
71161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
71175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
71195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
71205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
71215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
71225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "FooHeader: Bar\r\n\r\n"),
71235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
71265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
71275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
71285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
71295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
71305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
71315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
71345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
71365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
71385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
71405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
71415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
71435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
71445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
71455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
71475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
71485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
71495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
71505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader("referer", "www.foo.com");
71515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader("hEllo", "Kitty");
71525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader("FoO", "bar");
71535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
71555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
71561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
71575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
71595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
71605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
71615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
71625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "referer: www.foo.com\r\n"
71635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "hEllo: Kitty\r\n"
71645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "FoO: bar\r\n\r\n"),
71655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
71685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
71695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
71705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
71715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
71725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
71735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
71765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
71785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
71805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
71825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
71835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
71855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
71865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
71875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
71895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
71905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
71915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
71925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
71935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
71952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
71962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
7197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
71985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
72005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
72011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
72025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
72045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
72055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
72075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
72085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
72095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
72105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
72115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
72125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
72145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
72155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
72165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
72175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Payload"),
72185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
72195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
72205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
72225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
72245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
72265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
72285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
72295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
72315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
72325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
72345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
72355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
72372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
72382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
72392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
72402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_text;
72425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
72435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
72445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Payload", response_text);
72455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
72465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
72485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
72495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
72505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
72515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
72525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
72542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
72552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
7256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
72575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
72595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
72601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
72615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
72635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
72645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
72665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
72675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              arraysize(write_buffer)),
72685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
72695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
72705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
72715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
72725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
72745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
72755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(read_buffer)),
72765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
72775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
72785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Payload"),
72795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
72805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
72815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
72835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
72855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
7287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
72882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
72902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
72922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
72932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
72952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
72962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
72982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
72992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
73002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
73012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
73032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
73042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string response_text;
73062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
73072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
73082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("Payload", response_text);
73092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
73102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
73122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request;
73132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.method = "GET";
73142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.url = GURL("http://www.google.com/");
73152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.load_flags = 0;
73162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
73182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixed("socks4://myproxy:1080"));
73192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
7320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
73212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
73232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
73241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
73252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
73272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
73282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite data_writes[] = {
73302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
73312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
73322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
73332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
73342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
73352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead data_reads[] = {
73372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
73382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
73392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
73402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Payload"),
73412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
73422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
73432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
73452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                data_writes, arraysize(data_writes));
7346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
73475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
73495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
73515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
73525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
73545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
73555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
73575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
73585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
73602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
73612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
73622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
73632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_text;
73655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
73665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
73675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Payload", response_text);
73685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
73695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
73715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
73725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
73735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
73745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
73755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
73772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
73782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
7379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
73805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
73825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
73831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
73845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
73865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
73875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5OkRequest[] = {
73885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x05,  // Version
73895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01,  // Command (CONNECT)
73905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00,  // Reserved.
73915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03,  // Address type (DOMAINNAME).
73925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0E,  // Length of domain (14)
73935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Domain string:
73945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
73955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x50,  // 16-bit port (80)
73965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
73975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5OkResponse[] =
73985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
73995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
74015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
74025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
74035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
74045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
74055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
74065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
74075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
74095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
74105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
74115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
74125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
74135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Payload"),
74145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
74155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
74165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
74185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
74205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
74225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
74245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
74255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
74275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
74285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
74305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
74315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
74332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
74342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
74352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
74362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
74375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_text;
74385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
74395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
74405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Payload", response_text);
74415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
74425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
74445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
74455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
74465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
74475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
74485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
74502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
74512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
7452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
74535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
74555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
74561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
74575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
74595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
74605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char kSOCKS5OkRequest[] = {
74615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x05,  // Version
74625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01,  // Command (CONNECT)
74635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00,  // Reserved.
74645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03,  // Address type (DOMAINNAME).
74655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0E,  // Length of domain (14)
74665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Domain string:
74675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
74685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01, 0xBB,  // 16-bit port (443)
74695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
74705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5OkResponse[] =
74725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
74735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
74755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
74765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
74775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              arraysize(kSOCKS5OkRequest)),
74785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
74795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
74805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
74815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
74825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
74845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
74855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
74865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
74875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
74885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Payload"),
74895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
74905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
74915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
74935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
74955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
7497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
74985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
75005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
75025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
75035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
75055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
75065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
75085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
75095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
75112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
75122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
75132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
75142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
75155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_text;
75165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
75175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
75185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Payload", response_text);
75195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
75205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
75225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that for connection endpoints the group names are correctly set.
75245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct GroupNameTest {
75265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string proxy_server;
75275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
75285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string expected_group_name;
75295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ssl;
75305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
75315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
7533eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    NextProto next_proto,
7534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SpdySessionDependencies* session_deps_) {
7535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
75365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7537ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
75385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
75395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
75405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair("host.with.alternate", 80), 443,
7541116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AlternateProtocolFromNextProto(next_proto), 1);
75425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return session;
75445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
75455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GroupNameTransactionHelper(
75475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& url,
75485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const scoped_refptr<HttpNetworkSession>& session) {
75495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
75505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
75515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL(url);
75525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
75535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
7555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
75565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
75585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We do not complete this request, the dtor will clean the transaction up.
75605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return trans->Start(&request, callback.callback(), BoundNetLog());
75615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
75625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
75645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
75665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GroupNameTest tests[] = {
75675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
75685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
75695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://www.google.com/direct",
75705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "www.google.com:80",
75715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
75725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
75735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
75745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
75755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://[2001:1418:13:1::25]/direct",
75765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "[2001:1418:13:1::25]:80",
75775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
75785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
75795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SSL Tests
75815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
75825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
75835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://www.google.com/direct_ssl",
75845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/www.google.com:443",
75855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
75865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
75875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
75885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
75895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://[2001:1418:13:1::25]/direct",
75905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/[2001:1418:13:1::25]:443",
75915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
75925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
75935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
75945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
75955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://host.with.alternate/direct",
75965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/host.with.alternate:443",
75975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
75985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
75995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
76005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7601cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
76025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.proxy_service.reset(
76055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProxyService::CreateFixed(tests[i].proxy_server));
76065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(
7607eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SetupSessionForGroupNameTests(GetParam(), &session_deps_));
76085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpNetworkSessionPeer peer(session);
76105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameTransportSocketPool* transport_conn_pool =
76115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameTransportSocketPool(NULL, NULL);
76125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameSSLSocketPool* ssl_conn_pool =
76135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameSSLSocketPool(NULL, NULL);
7614f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7615f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new MockClientSocketPoolManager);
76165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
76175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
7618f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    peer.SetClientSocketPoolManager(
7619f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        mock_pool_manager.PassAs<ClientSocketPoolManager>());
76205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING,
76225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              GroupNameTransactionHelper(tests[i].url, session));
76235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tests[i].ssl)
76245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
76255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl_conn_pool->last_group_name_received());
76265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
76275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
76285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                transport_conn_pool->last_group_name_received());
76295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
76305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
76325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
76345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GroupNameTest tests[] = {
76355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
76365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http_proxy",
76375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://www.google.com/http_proxy_normal",
76385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "www.google.com:80",
76395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
76405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
76415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SSL Tests
76435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
76445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http_proxy",
76455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://www.google.com/http_connect_ssl",
76465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/www.google.com:443",
76475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
76485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
76495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
76515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http_proxy",
76525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://host.with.alternate/direct",
76535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/host.with.alternate:443",
76545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
76555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
76562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
76572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
76582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "http_proxy",
76592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "ftp://ftp.google.com/http_proxy_normal",
76602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "ftp/ftp.google.com:21",
76612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      false,
76622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    },
76635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
76645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7665cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
76665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.proxy_service.reset(
76695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProxyService::CreateFixed(tests[i].proxy_server));
76705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(
7671eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SetupSessionForGroupNameTests(GetParam(), &session_deps_));
76725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpNetworkSessionPeer peer(session);
76745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostPortPair proxy_host("http_proxy", 80);
76765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
76775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
76785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameSSLSocketPool* ssl_conn_pool =
76795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameSSLSocketPool(NULL, NULL);
76805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7681f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7682f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new MockClientSocketPoolManager);
76835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
76845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7685f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    peer.SetClientSocketPoolManager(
7686f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        mock_pool_manager.PassAs<ClientSocketPoolManager>());
76875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING,
76895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              GroupNameTransactionHelper(tests[i].url, session));
76905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tests[i].ssl)
76915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
76925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl_conn_pool->last_group_name_received());
76935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
76945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
76955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                http_proxy_pool->last_group_name_received());
76965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
76975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
76985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
77005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GroupNameTest tests[] = {
77015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
77025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4://socks_proxy:1080",
77035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://www.google.com/socks4_direct",
77045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4/www.google.com:80",
77055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
77065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
77075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
77085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks5://socks_proxy:1080",
77095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://www.google.com/socks5_direct",
77105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks5/www.google.com:80",
77115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
77125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
77135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SSL Tests
77155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
77165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4://socks_proxy:1080",
77175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://www.google.com/socks4_ssl",
77185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4/ssl/www.google.com:443",
77195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
77205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
77215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
77225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks5://socks_proxy:1080",
77235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://www.google.com/socks5_ssl",
77245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks5/ssl/www.google.com:443",
77255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
77265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
77275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
77295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4://socks_proxy:1080",
77305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://host.with.alternate/direct",
77315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4/ssl/host.with.alternate:443",
77325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
77335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
77345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
77355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7736cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
77375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.proxy_service.reset(
77405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProxyService::CreateFixed(tests[i].proxy_server));
77415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(
7742eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SetupSessionForGroupNameTests(GetParam(), &session_deps_));
77435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpNetworkSessionPeer peer(session);
77455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostPortPair proxy_host("socks_proxy", 1080);
77475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
77485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
77495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameSSLSocketPool* ssl_conn_pool =
77505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameSSLSocketPool(NULL, NULL);
77515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7752f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7753f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new MockClientSocketPoolManager);
77545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
77555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7756f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    peer.SetClientSocketPoolManager(
7757f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        mock_pool_manager.PassAs<ClientSocketPoolManager>());
77585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
7760868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
77615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING,
77635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              GroupNameTransactionHelper(tests[i].url, session));
77645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tests[i].ssl)
77655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
77665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl_conn_pool->last_group_name_received());
77675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
77685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
77695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                socks_conn_pool->last_group_name_received());
77705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
77715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
77725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
77745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
77755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
77765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
77775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
77795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("myproxy:70;foobar:80"));
77805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This simulates failure resolving all hostnames; that means we will fail
77825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connecting to both proxies (myproxy:70 and foobar:80).
7783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
77845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
77865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
77871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
77885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
77905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
77925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
77935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
77955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
77965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
77975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Base test to make sure that when the load flags for a request specify to
77995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bypass the cache, the DNS cache is not used.
78007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
7801c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int load_flags) {
78025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue a request, asking to bypass the cache(s).
78035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
78045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
78055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = load_flags;
78065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
78075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Select a host resolver that does caching.
7809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver.reset(new MockCachingHostResolver);
78105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
78128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
78131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
78145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Warm up the host cache so it has an entry for "www.google.com".
78165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList addrlist;
78175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
7818c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int rv = session_deps_.host_resolver->Resolve(
78193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
78203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      DEFAULT_PRIORITY,
78213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      &addrlist,
78223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      callback.callback(),
78233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      NULL,
78243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      BoundNetLog());
78255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
78265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
78275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
78285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that it was added to host cache, by doing a subsequent async lookup
78305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and confirming it completes synchronously.
7831c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  rv = session_deps_.host_resolver->Resolve(
78323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
78333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      DEFAULT_PRIORITY,
78343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      &addrlist,
78353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      callback.callback(),
78363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      NULL,
78373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      BoundNetLog());
78385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, rv);
78395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Inject a failure the next time that "www.google.com" is resolved. This way
78415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we can tell if the next lookup hit the cache, or the "network".
78425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (cache --> success, "network" --> failure).
7843c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
78445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
78465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // first read -- this won't be reached as the host resolution will fail first.
78475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
78485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
78505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run the request.
78525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
78535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, rv);
78545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
78555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we bypassed the cache, we would have gotten a failure while resolving
78575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "www.google.com".
78585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
78595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
78605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There are multiple load flags that should trigger the host cache bypass.
78625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test each in isolation:
78637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
78645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
78655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
78665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
78685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
78695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
78705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
78725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
78735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
78745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure we can handle an error when writing the request.
78767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
78775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
78785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
78795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
78805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
78815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite write_failure[] = {
78835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, ERR_CONNECTION_RESET),
78845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
78855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(NULL, 0,
78865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                write_failure, arraysize(write_failure));
7887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
78888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
78895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
78915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
78931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
78945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
78965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
78975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
78995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
79005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
79015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that a connection closed after the start of the headers finishes ok.
79037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
79045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
79055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
79065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
79075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
79085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
79105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1."),
79115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
79125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
79135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
79168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
79175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
79195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
79211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
79225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
79245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
79255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
79275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
79285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
79305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
79315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7932868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
79335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
79345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
79365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
79375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
79385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", response_data);
79395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
79405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that a dropped connection while draining the body for auth
79425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// restart does the right thing.
79437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
79445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
79455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
79465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
79475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
79485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
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\r\n"),
79535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
79545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
79565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
79575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
79585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
79595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 14\r\n\r\n"),
79605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Unauth"),
79615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_CONNECTION_RESET),
79625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
79635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
79655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
7966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
79675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), this is the request we should
79695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be issuing -- the final header line contains the credentials.
79705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
79715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
79725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
79735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
79745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
79755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
79765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
79785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
79795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
79805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
79815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
79825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
79835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
79845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
79865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
7987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
79888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
79895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
79915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
7993868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
79945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
79965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
79975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
79995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
80005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
80025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
80035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
80045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
80065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
80085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
80095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
80105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
80125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
80135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
80155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
80165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
80175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
80185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
80195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections going through a proxy that sends extra data.
80217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
8022c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
80235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
80255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
80265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
80275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
80285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead proxy_reads[] = {
80305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
80315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
80325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
80335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
80355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
80365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8037c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
8038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
80395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
80415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8042c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->ResetNextMockIndexes();
80435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
80455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
80461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
80475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
80495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
80505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
80525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
80535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
80545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
80565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
80575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
80585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
80595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
80605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
80625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
80631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
80645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
80665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
80675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
80685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
80695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8071c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
80725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
80745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
80765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
80775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
80795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
80815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
80825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8083868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
80845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
80855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
80875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
80885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
80895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
80905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
80922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath temp_file_path;
8093a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
80942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const uint64 kFakeSize = 100000;  // file is actually blank
80952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UploadFileElementReader::ScopedOverridingContentLengthForTests
80962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      overriding_content_length(kFakeSize);
80972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
80982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
80992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(
81007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      new UploadFileElementReader(base::MessageLoopProxy::current().get(),
81017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  temp_file_path,
81027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  0,
81037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  kuint64max,
81047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  base::Time()));
810568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
81062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
81075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
81085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
81095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/upload");
81102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.upload_data_stream = &upload_data_stream;
81115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
81125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
81145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
81151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
81165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
81185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),
81195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
81205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
81215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
81225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
81245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
81265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
81285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
81295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
81315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
81325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
81345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
81355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
81375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
81385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
81405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
81415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
81425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
81435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::DeleteFile(temp_file_path, false);
81455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
81465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
81482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath temp_file;
8149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
81502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string temp_file_content("Unreadable file.");
8151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
81522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   temp_file_content.length()));
81536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
81542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
81552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
81562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(
81577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      new UploadFileElementReader(base::MessageLoopProxy::current().get(),
81587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  temp_file,
81597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  0,
81607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  kuint64max,
81617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  base::Time()));
816268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
81632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
81645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
81655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
81665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/upload");
81672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.upload_data_stream = &upload_data_stream;
81685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
81695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If we try to upload an unreadable file, the transaction should fail.
81718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
81725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
81731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
81745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  StaticSocketDataProvider data(NULL, 0, NULL, 0);
8176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
81775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
81795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
81815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
81825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
8184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(ERR_ACCESS_DENIED, rv);
81855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
8187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(response);
81885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::DeleteFile(temp_file, false);
81905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
81915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
81934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  class FakeUploadElementReader : public UploadElementReader {
81944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   public:
81954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    FakeUploadElementReader() {}
81964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual ~FakeUploadElementReader() {}
81974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
81984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const CompletionCallback& callback() const { return callback_; }
81994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // UploadElementReader overrides:
82014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual int Init(const CompletionCallback& callback) OVERRIDE {
82024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      callback_ = callback;
82034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return ERR_IO_PENDING;
82044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
82054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual uint64 GetContentLength() const OVERRIDE { return 0; }
82064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual uint64 BytesRemaining() const OVERRIDE { return 0; }
82074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual int Read(IOBuffer* buf,
82084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                     int buf_length,
82094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                     const CompletionCallback& callback) OVERRIDE {
82104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return ERR_FAILED;
82114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
82124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   private:
82144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CompletionCallback callback_;
82154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
82164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
82184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
82194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  element_readers.push_back(fake_reader);
82204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
82214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  HttpRequestInfo request;
82234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.method = "POST";
82244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.url = GURL("http://www.google.com/upload");
82254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.upload_data_stream = &upload_data_stream;
82264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.load_flags = 0;
82274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
82294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
82301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
82314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StaticSocketDataProvider data;
82334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
82344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestCompletionCallback callback;
82364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
82374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
82384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
82394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Transaction is pending on request body initialization.
82414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_FALSE(fake_reader->callback().is_null());
82424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Return Init()'s result after the transaction gets destroyed.
82444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  trans.reset();
82454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  fake_reader->callback().Run(OK);  // Should not crash.
82464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
82474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that changes to Auth realms are treated like auth rejections.
82497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
82505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
82525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
82535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
82545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
82555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First transaction will request a resource and receive a Basic challenge
82575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // with realm="first_realm".
82585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
82595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
82605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
82615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
82625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
82635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
82655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"
82665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
82675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"),
82685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), provide an Authentication header
82715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for first_realm. The server will reject and provide a challenge with
82725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // second_realm.
82735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
82745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
82755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
82765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
82775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zmlyc3Q6YmF6\r\n"
82785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
82795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
82815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"
82825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
82835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"),
82845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This again fails, and goes back to first_realm. Make sure that the
82875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // entry is removed from cache.
82885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes3[] = {
82895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
82905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
82915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
82925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
82935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
82945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads3[] = {
82965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"
82975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
82985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"),
82995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
83005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try one last time (with the correct password) and get the resource.
83025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes4[] = {
83035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
83045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
83055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
83065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zmlyc3Q6YmFy\r\n"
83075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
83085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
83095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads4[] = {
83105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"
83115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Type: text/html; charset=iso-8859-1\r\n"
83125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 5\r\n"
83135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"
83145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "hello"),
83155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
83165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
83185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
83195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
83205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
83215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
83225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
83235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
83245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes4, arraysize(data_writes4));
8325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
8326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
8327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
8328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data4);
83295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
83315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
83335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
83341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
83355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the first request with Authorize headers. There should be a
83375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // password prompt for first_realm waiting to be filled in after the
83385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction completes.
83395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
83405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
83415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
83425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
83435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
83445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
83455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const AuthChallengeInfo* challenge = response->auth_challenge.get();
83465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(challenge == NULL);
83475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(challenge->is_proxy);
83485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
83495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("first_realm", challenge->realm);
83505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", challenge->scheme);
83515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the second request with an incorrect password. There should be a
83535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // password prompt for second_realm waiting to be filled in after the
83545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction completes.
83555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
83565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
83575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFirst, kBaz), callback2.callback());
83585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
83595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
83605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
83615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
83625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
83635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  challenge = response->auth_challenge.get();
83645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(challenge == NULL);
83655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(challenge->is_proxy);
83665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
83675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("second_realm", challenge->realm);
83685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", challenge->scheme);
83695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the third request with another incorrect password. There should be
83715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a password prompt for first_realm waiting to be filled in. If the password
83725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // prompt is not present, it indicates that the HttpAuthCacheEntry for
83735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // first_realm was not correctly removed.
83745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
83755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
83765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kSecond, kFou), callback3.callback());
83775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
83785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
83795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
83805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
83815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
83825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  challenge = response->auth_challenge.get();
83835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(challenge == NULL);
83845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(challenge->is_proxy);
83855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
83865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("first_realm", challenge->realm);
83875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", challenge->scheme);
83885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the fourth request with the correct password and username.
83905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback4;
83915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
83925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFirst, kBar), callback4.callback());
83935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
83945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback4.WaitForResult();
83955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
83965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
83975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
83985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
83995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
84005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
8402cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
8403cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
84045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
8406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
8407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
84085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
84095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8410eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
84115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
84125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
84135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
84145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
84165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
84175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
84185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
84195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
84215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
84235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
84255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
84272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8428868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
84295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
84315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
84325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair http_host_port_pair("www.google.com", 80);
8434a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  HttpServerProperties& http_server_properties =
84355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *session->http_server_properties();
84365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
84375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_server_properties.HasAlternateProtocol(http_host_port_pair));
84385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
84405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
84425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8443868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
84445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
84455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
84465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_npn_negotiated);
84475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
84495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
84505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
84515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
8453116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const AlternateProtocolInfo alternate =
84545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_server_properties.GetAlternateProtocol(http_host_port_pair);
8455116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AlternateProtocolInfo expected_alternate(
8456116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      443, AlternateProtocolFromNextProto(GetParam()), 1);
84575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(expected_alternate.Equals(alternate));
84585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
84595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
84615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       MarkBrokenAlternateProtocolAndFallback) {
8462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
84635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
84655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
84665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
84675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
84685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
84705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
84715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
84735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
84755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
84765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
84775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
84785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
84795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
84805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
84825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
84845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8485ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
84865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
84875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Port must be < 1024, or the header will be ignored (since initial port was
84885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // port 80 (another restricted port).
84895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
84905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(request.url),
84915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      666 /* port is ignored by MockConnect anyway */,
8492116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AlternateProtocolFromNextProto(GetParam()), 1);
84935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8495868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
84965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
84975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
84995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
85005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
85015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
85035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8504868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
85055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
85065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
85085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
85095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
85105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
85125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(request.url)));
8513116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const AlternateProtocolInfo alternate =
85145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_server_properties->GetAlternateProtocol(
85155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          HostPortPair::FromURL(request.url));
85165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
85175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
85185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
85205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolPortRestrictedBlocked) {
85215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
85225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
85235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a restricted port (port < 1024).  Ensure that we can redirect in all
85245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other cases.
8525cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
85265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo restricted_port_request;
85285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.method = "GET";
85295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.url = GURL("http://www.google.com:1023/");
85305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.load_flags = 0;
85315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
85335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
85345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
85365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
85385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
85395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
85405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
85415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
85425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
85435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
85455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
85475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8548ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
85495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
85505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kUnrestrictedAlternatePort = 1024;
85515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
85525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(restricted_port_request.url),
85535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUnrestrictedAlternatePort,
8554116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AlternateProtocolFromNextProto(GetParam()), 1);
85555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8557868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
85585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
85595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(
85612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &restricted_port_request,
85622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback.callback(), BoundNetLog());
85635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
85645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invalid change to unrestricted port should fail.
85655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
85662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
85675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
85692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       AlternateProtocolPortRestrictedPermitted) {
85702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ensure that we're allowed to redirect traffic via an alternate
85712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
85722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // on a restricted port (port < 1024) if we set
85732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // enable_user_alternate_protocol_ports.
85742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8575cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
8576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.enable_user_alternate_protocol_ports = true;
85772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
85782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo restricted_port_request;
85792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  restricted_port_request.method = "GET";
85802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  restricted_port_request.url = GURL("http://www.google.com:1023/");
85812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  restricted_port_request.load_flags = 0;
85822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
85832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
85842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider first_data;
85852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  first_data.set_connect_data(mock_connect);
8586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
85872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
85882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead data_reads[] = {
85892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
85902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("hello world"),
85912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, OK),
85922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
85932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider second_data(
85942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
85962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
85982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8599ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
86002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      session->http_server_properties();
86012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kUnrestrictedAlternatePort = 1024;
86022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  http_server_properties->SetAlternateProtocol(
86032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HostPortPair::FromURL(restricted_port_request.url),
86042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kUnrestrictedAlternatePort,
8605116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AlternateProtocolFromNextProto(GetParam()), 1);
86062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
86072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8608868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
86092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
86102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
86112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, trans->Start(
86122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &restricted_port_request,
86132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback.callback(), BoundNetLog()));
86142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Change to unrestricted port should succeed.
86152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
86165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
86175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
86195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolPortRestrictedAllowed) {
86205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
86215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
86225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a restricted port (port < 1024).  Ensure that we can redirect in all
86235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other cases.
8624cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
86255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo restricted_port_request;
86275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.method = "GET";
86285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.url = GURL("http://www.google.com:1023/");
86295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.load_flags = 0;
86305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
86325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
86335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
86355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
86375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
86385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
86395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
86405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
86415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
86425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
86445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
86465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8647ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
86485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
86495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kRestrictedAlternatePort = 80;
86505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
86515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(restricted_port_request.url),
86525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kRestrictedAlternatePort,
8653116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AlternateProtocolFromNextProto(GetParam()), 1);
86545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8656868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
86575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
86585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(
86602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &restricted_port_request,
86612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback.callback(), BoundNetLog());
86625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
86635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Valid change to restricted port should pass.
86645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
86655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
86665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
86685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolPortUnrestrictedAllowed1) {
86695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
86705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
86715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a restricted port (port < 1024).  Ensure that we can redirect in all
86725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other cases.
8673cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
86745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo unrestricted_port_request;
86765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.method = "GET";
86775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.url = GURL("http://www.google.com:1024/");
86785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.load_flags = 0;
86795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
86815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
86825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
86845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
86865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
86875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
86885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
86895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
86905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
86915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
86935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
86955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8696ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
86975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
86985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kRestrictedAlternatePort = 80;
86995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
87005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(unrestricted_port_request.url),
87015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kRestrictedAlternatePort,
8702116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AlternateProtocolFromNextProto(GetParam()), 1);
87035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8705868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
87065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
87075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(
87095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &unrestricted_port_request, callback.callback(), BoundNetLog());
87105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
87115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Valid change to restricted port should pass.
87125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
87135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
87145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
87165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolPortUnrestrictedAllowed2) {
87175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
87185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
87195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a restricted port (port < 1024).  Ensure that we can redirect in all
87205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other cases.
8721cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
87225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo unrestricted_port_request;
87245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.method = "GET";
87255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.url = GURL("http://www.google.com:1024/");
87265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.load_flags = 0;
87275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
87295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
87305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
87325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
87345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
87355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
87365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
87375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
87385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
87395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
87415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
87435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8744ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
87455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
87465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kUnrestrictedAlternatePort = 1024;
87475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
87485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(unrestricted_port_request.url),
87495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUnrestrictedAlternatePort,
8750116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AlternateProtocolFromNextProto(GetParam()), 1);
87515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8753868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
87545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
87555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(
87575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &unrestricted_port_request, callback.callback(), BoundNetLog());
87585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
87595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Valid change to an unrestricted port should pass.
87605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
87615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
87625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8763cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
87645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
87655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unsafe port, and that we resume the second
87665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
8767cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
87685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
87705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
87715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
87725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
87735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The alternate protocol request will error out before we attempt to connect,
87755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so only the standard HTTP request will try to connect.
87765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
87775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
87785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
87795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
87805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
87815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(
87825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
87845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
87865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8787ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
87885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
87895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kUnsafePort = 7;
87905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
87915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(request.url),
87925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUnsafePort,
8793116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AlternateProtocolFromNextProto(GetParam()), 1);
87945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8796868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
87975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
87985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
88005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
88015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The HTTP request should succeed.
88025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
88035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disable alternate protocol before the asserts.
8805cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // HttpStreamFactory::set_use_alternate_protocols(false);
88065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
88085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8809868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
88105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
88115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
88135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
88145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
88155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
88165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
8818cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
8819cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
88205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
88225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
88235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
88245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
88255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8826eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
8827eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
8828eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
88295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
88305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8831eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
88325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
88335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
88345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK)
88355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
88365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
88385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8839c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
88405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
88427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
8843c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
88445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
884590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
884690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
88475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
88485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
88507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
88515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
88525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
88535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data),
88545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
88555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
88565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
88585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
88595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
88605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
8861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
88625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
88645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_non_alternate_protocol_socket(
88655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
88665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_non_alternate_protocol_socket.set_connect_data(
88675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      never_finishing_connect);
8868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(
88695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &hanging_non_alternate_protocol_socket);
88705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
88725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
88742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8875868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
88765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
88785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
88795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
88805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
88825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8883868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
88845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
88855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
88875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
88885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
88895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8890868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
88915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
88935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
88945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
88955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
88975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8898868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
88995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
89005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
89015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
89025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
89045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
89055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
89065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
8908cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
8909cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
89105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
89125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
89135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
89145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
89155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8916eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
8917eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
8918eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
89195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
89205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8921eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
89225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
89235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
89245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
89255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
89265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
89285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
89295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
8930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
89315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
89335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_socket(
89345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
89355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_socket.set_connect_data(never_finishing_connect);
89365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket 2 and 3 are the hanging Alternate-Protocol and
89375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // non-Alternate-Protocol jobs from the 2nd transaction.
8938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
89405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
89427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
8943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
89445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
894590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(
894690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
894790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
894890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
89495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
89505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req1),
89515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2),
89525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
89537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
89547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
89557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
89567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
89575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
89585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp1),
89595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data1),
89605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2),
89615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data2),
89625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
89635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
89645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
89665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      2,  // wait for writes to finish before reading.
89675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
89685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
89695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket 4 is the successful Alternate-Protocol for transaction 3.
8970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
89715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
8973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
89745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
89765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
8977868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
89785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
89805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
89815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
89825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans1.GetResponseInfo();
89845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8985868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
89865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
89875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
89895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
89905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
89915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
8993868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
89945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
89955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
89965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
8998868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
89995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
90005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
90015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
90035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback3.WaitForResult());
90045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans2.GetResponseInfo();
90065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9007868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
90085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
90095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
90105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
90115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
90125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
90135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans3.GetResponseInfo();
90155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9016868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
90175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
90185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
90195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
90205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
90215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
90225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
90235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
9025cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
9026cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
90275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
90295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
90305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
90315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
90325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9033eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
9034eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
9035eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
90365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
90375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
9038eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
90395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
90405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
90415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
90425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
90435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
90455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
9046c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
90475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
90497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
9050c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
90515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
90535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_alternate_protocol_socket(
90545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
90555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_alternate_protocol_socket.set_connect_data(
90565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      never_finishing_connect);
9057c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(
90585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &hanging_alternate_protocol_socket);
90595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2nd request is just a copy of the first one, over HTTP again.
9061c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
90625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
90645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9065c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
90662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9067868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
90685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
90705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
90715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
90725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
90745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9075868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
90765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
90775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
90795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
90805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
90815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9082868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
90835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
90855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
90865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
90875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
90895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9090868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
90915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
90925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
90935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_npn_negotiated);
90945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
90965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
90975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
90985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CapturingProxyResolver : public ProxyResolver {
91005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
91015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
91025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~CapturingProxyResolver() {}
91035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetProxyForURL(const GURL& url,
91055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ProxyInfo* results,
91065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const CompletionCallback& callback,
91075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             RequestHandle* request,
91082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const BoundNetLog& net_log) OVERRIDE {
91095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
91105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             HostPortPair("myproxy", 80));
91115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    results->UseProxyServer(proxy_server);
91125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resolved_.push_back(url);
91135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
91145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
91155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void CancelRequest(RequestHandle request) OVERRIDE {
91175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
91185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
91195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
91215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
91225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return LOAD_STATE_IDLE;
91235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
91245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void CancelSetPacScript() OVERRIDE {
91265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
91275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
91285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
91302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const CompletionCallback& /*callback*/) OVERRIDE {
91315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
91325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
91335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::vector<GURL>& resolved() const { return resolved_; }
91355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
91375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<GURL> resolved_;
91385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
91405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
91415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
91435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       UseAlternateProtocolForTunneledNpnSpdy) {
9144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
9145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
91465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig proxy_config;
91485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxy_config.set_auto_detect(true);
91495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxy_config.set_pac_url(GURL("http://fooproxyurl"));
91505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingProxyResolver* capturing_proxy_resolver =
91525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new CapturingProxyResolver();
9153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(new ProxyService(
91545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
91555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL));
91562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
9157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
91585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
91605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
91615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
91625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
91635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
9165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
9166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
91675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
91685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
9169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
91705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
91715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
91725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
91735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
91745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
91765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
9177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
91785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
91807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
9181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
91825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
918390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
918490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
91855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
91865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
91875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
91885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),  // 0
918990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CreateMockWrite(*req),                              // 3
91905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
91915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
91935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
91957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
91965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
91975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1),  // 1
91985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp.get(), 4),  // 2, 4
91995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data.get(), 4),  // 5
92005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0, 4),  // 6
92015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
92025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
92045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
92055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
9206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
92075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
92095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_non_alternate_protocol_socket(
92105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
92115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_non_alternate_protocol_socket.set_connect_data(
92125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      never_finishing_connect);
9213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(
92145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &hanging_non_alternate_protocol_socket);
92155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
92175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
92192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
92215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
92235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
92245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
92255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
92275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
92295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
92305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
92315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_npn_negotiated);
92325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
92345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
92355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
92365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
92385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
92405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
92415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
92425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
92445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
92465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
92475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
92485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
92495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
92515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
92525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
92535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://www.google.com/",
92545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            capturing_proxy_resolver->resolved()[0].spec());
92555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("https://www.google.com/",
92565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            capturing_proxy_resolver->resolved()[1].spec());
92575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
92592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
92602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
92612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
92625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
92635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
92655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
9266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
9267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
92685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
92705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
92715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
92725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
92735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
9275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
9276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
92775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
92785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
9279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
92805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
92815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
92825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
92835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
92855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
9286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
92875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
92897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
9290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
92915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
929290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
929390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
92945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
92955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
92977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
92985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
92995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
93005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data),
93015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
93025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
93035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
93055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
93065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
93075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
9308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
93095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
93115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
93135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
93165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
93185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
93195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
93205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
93225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
93245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
93255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
93275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
93285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
93295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up an initial SpdySession in the pool to reuse.
93315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair host_port_pair("www.google.com", 443);
933290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
9333e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                     PRIVACY_MODE_DISABLED);
9334ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<SpdySession> spdy_session =
93357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      CreateSecureSpdySession(session, key, BoundNetLog());
93365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
93385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
93405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
93415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
93425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
93445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
93465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
93475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
93485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
93495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
93515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
93525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
93535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GenerateAuthToken is a mighty big test.
93555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It tests all permutation of GenerateAuthToken behavior:
93565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - Synchronous and Asynchronous completion.
93575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - OK or error on completion.
93585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - Direct connection, non-authenticating proxy, and authenticating proxy.
93595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - HTTP or HTTPS backend (to include proxy tunneling).
93605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - Non-authenticating and authenticating backend.
93615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
93625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In all, there are 44 reasonable permuations (for example, if there are
93635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// problems generating an auth token for an authenticating proxy, we don't
93645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// need to test all permutations of the backend server).
93655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
93665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The test proceeds by going over each of the configuration cases, and
93675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// potentially running up to three rounds in each of the tests. The TestConfig
93685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specifies both the configuration for the test as well as the expectations
93695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for the results.
93707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
93715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kServer[] = "http://www.example.com";
93725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kSecureServer[] = "https://www.example.com";
93735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kProxy[] = "myproxy:70";
93745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
93755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum AuthTiming {
93775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AUTH_NONE,
93785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AUTH_SYNC,
93795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AUTH_ASYNC,
93805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
93815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGet(
93835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET / HTTP/1.1\r\n"
93845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
93855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Connection: keep-alive\r\n\r\n");
93865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetProxy(
93875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET http://www.example.com/ HTTP/1.1\r\n"
93885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
93895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n\r\n");
93905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetAuth(
93915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET / HTTP/1.1\r\n"
93925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
93935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Connection: keep-alive\r\n"
93945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Authorization: auth_token\r\n\r\n");
93955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetProxyAuth(
93965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET http://www.example.com/ 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)  const MockWrite kGetAuthThroughProxy(
94015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET http://www.example.com/ HTTP/1.1\r\n"
94025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
94035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n"
94045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Authorization: auth_token\r\n\r\n");
94055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetAuthWithProxyAuth(
94065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET http://www.example.com/ HTTP/1.1\r\n"
94075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
94085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n"
94095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Authorization: auth_token\r\n"
94105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Authorization: auth_token\r\n\r\n");
94115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kConnect(
94125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "CONNECT www.example.com:443 HTTP/1.1\r\n"
94135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
94145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n\r\n");
94155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kConnectProxyAuth(
94165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "CONNECT www.example.com:443 HTTP/1.1\r\n"
94175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
94185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n"
94195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Authorization: auth_token\r\n\r\n");
94205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kSuccess(
94225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\r\n"
94235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
94245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 3\r\n\r\n"
94255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Yes");
94265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kFailure(
94275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Should not be called.");
94285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kServerChallenge(
94295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 401 Unauthorized\r\n"
94305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "WWW-Authenticate: Mock realm=server\r\n"
94315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
94325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 14\r\n\r\n"
94335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Unauthorized\r\n");
94345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kProxyChallenge(
94355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 407 Unauthorized\r\n"
94365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Authenticate: Mock realm=proxy\r\n"
94375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: close\r\n"
94385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
94395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 14\r\n\r\n"
94405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Unauthorized\r\n");
94415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kProxyConnected(
94425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 Connection Established\r\n\r\n");
94435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
94455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // no constructors, but the C++ compiler on Windows warns about
94465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // unspecified data in compound literals. So, moved to using constructors,
94475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and TestRound's created with the default constructor should not be used.
94485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct TestRound {
94495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRound()
94505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : expected_rv(ERR_UNEXPECTED),
94515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_write(NULL),
94525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_read(NULL) {
94535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
94545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRound(const MockWrite& write_arg, const MockRead& read_arg,
94555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              int expected_rv_arg)
94565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : write(write_arg),
94575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          read(read_arg),
94585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          expected_rv(expected_rv_arg),
94595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_write(NULL),
94605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_read(NULL) {
94615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
94625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRound(const MockWrite& write_arg, const MockRead& read_arg,
94635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              int expected_rv_arg, const MockWrite* extra_write_arg,
94645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              const MockRead* extra_read_arg)
94655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : write(write_arg),
94665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          read(read_arg),
94675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          expected_rv(expected_rv_arg),
94685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_write(extra_write_arg),
94695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_read(extra_read_arg) {
94705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
94715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite write;
94725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead read;
94735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int expected_rv;
94745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockWrite* extra_write;
94755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockRead* extra_read;
94765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
94775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kNoSSL = 500;
94795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct TestConfig {
94815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* proxy_url;
94825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AuthTiming proxy_auth_timing;
94835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int proxy_auth_rv;
94845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* server_url;
94855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AuthTiming server_auth_timing;
94865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int server_auth_rv;
94875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int num_auth_rounds;
94885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int first_ssl_round;
94895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRound rounds[3];
94905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } test_configs[] = {
94915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTP server with a direct connection.
94925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
94935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kSuccess, OK)}},
94945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTP server with a direct connection.
94955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
94965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
94975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
94985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
94995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
95005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
95015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
95025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
95035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
95045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
95055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
95065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
95075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTP server through a non-authenticating proxy.
95085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
95095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kSuccess, OK)}},
95105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTP server through a non-authenticating proxy.
95115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
95125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kServerChallenge, OK),
95135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
95145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
95155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kServerChallenge, OK),
95165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
95175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
95185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kServerChallenge, OK),
95195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
95205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
95215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kServerChallenge, OK),
95225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
95235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTP server through an authenticating proxy.
95245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
95255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kSuccess, OK)}},
95275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
95285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
95305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
95315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kSuccess, OK)}},
95335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
95345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
95365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTP server through an authenticating proxy.
95375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
95385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
95415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
95425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
95455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
95465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
95495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
95505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
95535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
95545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
95575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
95585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
95615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
95625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
95655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
95665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
95695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTPS server with a direct connection.
95705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
95715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kSuccess, OK)}},
95725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTPS server with a direct connection.
95735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
95745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
95755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
95765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
95775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
95785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
95795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
95805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
95815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
95825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
95835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
95845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
95855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTPS server with a non-authenticating proxy.
95865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
95875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
95885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTPS server through a non-authenticating proxy.
95895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
95905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
95915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
95925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
95935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
95945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
95955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
95965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
95975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
95985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
95995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
96005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
96015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-Authenticating HTTPS server through an authenticating proxy.
96025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
96035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
96055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
96065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
96085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
96095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
96115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
96125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
96145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTPS server through an authenticating proxy.
96155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, 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_SYNC, 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_SYNC, 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_SYNC, 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)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
96365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
96385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
96395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
96405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
96415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
96435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
96445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
96455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
96465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
96485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
96495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
96505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
96515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
96535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
96545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
96555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
96565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
96585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpAuthHandlerMock::Factory* auth_factory(
96595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new HttpAuthHandlerMock::Factory());
9660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.http_auth_handler_factory.reset(auth_factory);
96615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const TestConfig& test_config = test_configs[i];
96625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Set up authentication handlers as necessary.
96645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_config.proxy_auth_timing != AUTH_NONE) {
96655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (int n = 0; n < 2; n++) {
96665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
96675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::string auth_challenge = "Mock realm=proxy";
96685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL origin(test_config.proxy_url);
9669a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9670a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             auth_challenge.end());
96715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
96725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        origin, BoundNetLog());
96735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        auth_handler->SetGenerateExpectation(
96745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            test_config.proxy_auth_timing == AUTH_ASYNC,
96755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            test_config.proxy_auth_rv);
96765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
96775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
96785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
96795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_config.server_auth_timing != AUTH_NONE) {
96805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
96815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string auth_challenge = "Mock realm=server";
96825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL origin(test_config.server_url);
9683a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9684a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                           auth_challenge.end());
96855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
96865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      origin, BoundNetLog());
96875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      auth_handler->SetGenerateExpectation(
96885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          test_config.server_auth_timing == AUTH_ASYNC,
96895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          test_config.server_auth_rv);
96905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
96915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
96925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_config.proxy_url) {
9693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.proxy_service.reset(
96945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ProxyService::CreateFixed(test_config.proxy_url));
96955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
9696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.proxy_service.reset(ProxyService::CreateDirect());
96975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
96985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
97005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
97015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL(test_config.server_url);
97025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
97035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
97051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
97065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int round = 0; round < test_config.num_auth_rounds; ++round) {
97085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const TestRound& read_write_round = test_config.rounds[round];
97095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Set up expected reads and writes.
97115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead reads[2];
97125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reads[0] = read_write_round.read;
97135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t length_reads = 1;
97145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (read_write_round.extra_read) {
97155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reads[1] = *read_write_round.extra_read;
97165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        length_reads = 2;
97175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
97185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite writes[2];
97205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writes[0] = read_write_round.write;
97215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t length_writes = 1;
97225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (read_write_round.extra_write) {
97235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        writes[1] = *read_write_round.extra_write;
97245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        length_writes = 2;
97255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
97265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      StaticSocketDataProvider data_provider(
97275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          reads, length_reads, writes, length_writes);
9728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
97295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Add an SSL sequence if necessary.
97315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
97325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (round >= test_config.first_ssl_round)
9733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        session_deps_.socket_factory->AddSSLSocketDataProvider(
97345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &ssl_socket_data_provider);
97355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Start or restart the transaction.
97375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestCompletionCallback callback;
97385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int rv;
97395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (round == 0) {
97405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = trans.Start(&request, callback.callback(), BoundNetLog());
97415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
97425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = trans.RestartWithAuth(
97435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            AuthCredentials(kFoo, kBar), callback.callback());
97445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
97455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (rv == ERR_IO_PENDING)
97465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = callback.WaitForResult();
97475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Compare results with expected data.
97495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(read_write_round.expected_rv, rv);
97505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const HttpResponseInfo* response = trans.GetResponseInfo();
97515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (read_write_round.expected_rv == OK) {
97525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ASSERT_TRUE(response != NULL);
97535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
97545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(response == NULL);
97555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_EQ(round + 1, test_config.num_auth_rounds);
97565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
97575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
97585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (round + 1 < test_config.num_auth_rounds) {
97595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_FALSE(response->auth_challenge.get() == NULL);
97605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
97615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(response->auth_challenge.get() == NULL);
97625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
97635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
97645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
97655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
97665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
97685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do multi-round authentication and make sure it works correctly.
97695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerMock::Factory* auth_factory(
97705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new HttpAuthHandlerMock::Factory());
9771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.http_auth_handler_factory.reset(auth_factory);
9772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->set_synchronous_mode(true);
97755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
97775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->set_connection_based(true);
97785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string auth_challenge = "Mock realm=server";
97795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL origin("http://www.example.com");
9780a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9781a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                       auth_challenge.end());
97825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
97835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  origin, BoundNetLog());
97845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
97855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = OK;
97875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = NULL;
97885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
97895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
97905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = origin;
97915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
97925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9793c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
97945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use a TCP Socket Pool with only one connection per group. This is used
97965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to validate that the TCP socket is not released to the pool between
97975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // each round of multi-round authentication.
97985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpNetworkSessionPeer session_peer(session);
97995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
98005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
98015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50,  // Max sockets for pool
98025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,   // Max sockets per group
98035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &transport_pool_histograms,
9804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.host_resolver.get(),
9805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.socket_factory.get(),
9806c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.net_log);
9807f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
9808f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new MockClientSocketPoolManager);
98095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_pool_manager->SetTransportSocketPool(transport_pool);
9810f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  session_peer.SetClientSocketPoolManager(
9811f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      mock_pool_manager.PassAs<ClientSocketPoolManager>());
98125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9814868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
98155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
98165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGet(
98185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET / HTTP/1.1\r\n"
98195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
98205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Connection: keep-alive\r\n\r\n");
98215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetAuth(
98225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET / HTTP/1.1\r\n"
98235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
98245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Connection: keep-alive\r\n"
98255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Authorization: auth_token\r\n\r\n");
98265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kServerChallenge(
98285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 401 Unauthorized\r\n"
98295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "WWW-Authenticate: Mock realm=server\r\n"
98305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
98315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 14\r\n\r\n"
98325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Unauthorized\r\n");
98335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kSuccess(
98345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\r\n"
98355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
98365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 3\r\n\r\n"
98375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Yes");
98385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
98405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First round
98415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGet,
98425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Second round
98435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGetAuth,
98445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Third round
98455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGetAuth,
98465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fourth round
98475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGetAuth,
98485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Competing request
98495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGet,
98505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
98515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
98525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First round
98535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kServerChallenge,
98545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Second round
98555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kServerChallenge,
98565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Third round
98575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kServerChallenge,
98585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fourth round
98595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kSuccess,
98605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Competing response
98615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kSuccess,
98625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
98635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data_provider(reads, arraysize(reads),
98645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         writes, arraysize(writes));
9865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
98665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kSocketGroup = "www.example.com:80";
98685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First round of authentication.
98705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->SetGenerateExpectation(false, OK);
98715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
98725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
98735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
98745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
98755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
98765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
98775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->auth_challenge.get() == NULL);
98785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
98795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In between rounds, another request comes in for the same domain.
98815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It should not be able to grab the TCP socket that trans has already
98825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // claimed.
98835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans_compete(
9884868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
98855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_compete;
98865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans_compete->Start(
98875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &request, callback_compete.callback(), BoundNetLog());
98885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
98895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // callback_compete.WaitForResult at this point would stall forever,
98905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since the HttpNetworkTransaction does not release the request back to
98915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the pool until after authentication completes.
98925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second round of authentication.
98945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->SetGenerateExpectation(false, OK);
98955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
98965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
98975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
98985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
98995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
99005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
99015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
99025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
99035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Third round of authentication.
99055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->SetGenerateExpectation(false, OK);
99065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
99075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
99085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
99095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
99105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
99115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
99125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
99135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
99145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fourth round of authentication, which completes successfully.
99165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->SetGenerateExpectation(false, OK);
99175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
99185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
99195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
99205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
99215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
99225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
99235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
99245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
99255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read the body since the fourth round was successful. This will also
99275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // release the socket back to the pool.
99285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
9929868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
99305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
99315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
99325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, rv);
9933868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
99345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, rv);
99355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There are still 0 idle sockets, since the trans_compete transaction
99365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will be handed it immediately after trans releases it to the group.
99375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
99385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The competing request can now finish. Wait for the headers and then
99405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // read the body.
99415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback_compete.WaitForResult();
99425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
9943868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
99445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
99455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
99465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, rv);
9947868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
99485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, rv);
99495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finally, the socket is released to the group.
99515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
99525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
99535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This tests the case that a request is issued via http instead of spdy after
99555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// npn is negotiated.
99567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
9957cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
9958cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NextProtoVector next_protos;
9959ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  next_protos.push_back(kProtoHTTP11);
9960cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = next_protos;
9961cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
99625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
99635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
99645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
99655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
99665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
99685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
99695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
99705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
99715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
99725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9973eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
9974eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
9975eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
99765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
99775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
9978eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
99795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
99805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
99815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
99825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
99845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
99855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl.next_proto = "http/1.1";
99865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl.protocol_negotiated = kProtoHTTP11;
99875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
99895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
99915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
9992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
99935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
99955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
99972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9998868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
99995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
100015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
100035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
100045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
100065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10007868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
100085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
100095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
100115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
100125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
100135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
100155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
100165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
100175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
100195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate the SSL handshake completing with an NPN negotiation
100205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // followed by an immediate server closing of the socket.
100215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fix crash:  http://crbug.com/46369
10022cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
10023cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
100245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
100265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
100275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
100285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
100295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
100317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
10032c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
100335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1003490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
1003590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
100365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
100375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
100395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, 0, 0)   // Not async - return 0 immediately.
100405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
100415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
100435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,  // don't wait in this case, immediate hangup.
100445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
100455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
10046c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
100475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
100495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10050c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
100512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10052868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
100535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
100555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
100565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
100575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
100585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10059ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// A subclass of HttpAuthHandlerMock that records the request URL when
10060ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// it gets it. This is needed since the auth handler may get destroyed
10061ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// before we get a chance to query it.
10062ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10063ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch public:
10064ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10065ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
10066ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual ~UrlRecordingHttpAuthHandlerMock() {}
10067ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
10068ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch protected:
10069ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10070ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                    const HttpRequestInfo* request,
10071ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                    const CompletionCallback& callback,
10072ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                    std::string* auth_token) OVERRIDE {
10073ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    *url_ = request->url;
10074ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10075ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        credentials, request, callback, auth_token);
10076ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
10077ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
10078ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch private:
10079ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  GURL* url_;
10080ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch};
10081ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
100827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
100835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This test ensures that the URL passed into the proxy is upgraded
100845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to https when doing an Alternate Protocol upgrade.
10085cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
10086cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
100875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10088c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
100892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
100902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
10091c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
10092ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  GURL request_url;
10093ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  {
10094ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    HttpAuthHandlerMock::Factory* auth_factory =
10095ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        new HttpAuthHandlerMock::Factory();
10096ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    UrlRecordingHttpAuthHandlerMock* auth_handler =
10097ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        new UrlRecordingHttpAuthHandlerMock(&request_url);
10098ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10099ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    auth_factory->set_do_init_from_challenge(true);
10100ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    session_deps_.http_auth_handler_factory.reset(auth_factory);
10101ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
101025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
101045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
101055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com");
101065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
101075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First round goes unauthenticated through the proxy.
101095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes_1[] = {
101105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
101115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
101125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
101135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
101145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
101155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads_1[] = {
101165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
101175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"
101185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Alternate-Protocol: 443:npn-spdy/2\r\n"
101195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Proxy-Connection: close\r\n"
101205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"),
101215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
101225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
101235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  data_writes_1, arraysize(data_writes_1));
101245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second round tries to tunnel to www.google.com due to the
101265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Alternate-Protocol announcement in the first round. It fails due
101275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to a proxy authentication challenge.
101285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the failure, a tunnel is established to www.google.com using
101295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Proxy-Authorization headers. There is then a SPDY request round.
101305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
101315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: Despite the "Proxy-Connection: Close", these are done on the
101325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
101335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // does a Disconnect and Connect on the same socket, rather than trying
101345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to obtain a new one.
101355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
101365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: Originally, the proxy response to the second CONNECT request
101375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // simply returned another 407 so the unit test could skip the SSL connection
101385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // establishment and SPDY framing issues. Alas, the
101395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // retry-http-when-alternate-protocol fails logic kicks in, which was more
101405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // complicated to set up expectations for than the SPDY session.
101415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1014290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
1014390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
101447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
101457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
101465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes_2[] = {
101485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First connection attempt without Proxy-Authorization.
101495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
101505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
101515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
101525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
101535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Second connection attempt with Proxy-Authorization.
101555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
101565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
101575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
101585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: auth_token\r\n"
101595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
101605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SPDY request
101625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req),
101635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
101645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
101655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         "Proxy-Authenticate: Mock\r\n"
101665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         "Proxy-Connection: close\r\n"
101675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         "\r\n");
101685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
101695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads_2[] = {
101705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First connection attempt fails
101715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
101725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kRejectConnectResponse,
101735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(kRejectConnectResponse) - 1, 1),
101745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Second connection attempt passes
101765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kAcceptConnectResponse,
101775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(kAcceptConnectResponse) -1, 4),
101785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SPDY response
101805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp.get(), 6),
101815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data.get(), 6),
101825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0, 6),
101835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
101845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data_2(
101855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads_2, arraysize(data_reads_2),
101865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_writes_2, arraysize(data_writes_2));
101875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
101897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
101905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
101925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_non_alternate_protocol_socket(
101935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
101945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_non_alternate_protocol_socket.set_connect_data(
101955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      never_finishing_connect);
101965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(
102015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &hanging_non_alternate_protocol_socket);
10202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
102035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First round should work and provide the Alternate-Protocol state.
102055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_1;
102062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans_1(
10207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
102085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
102095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
102105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback_1.WaitForResult());
102115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second round should attempt a tunnel connect and get an auth challenge.
102135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_2;
102142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans_2(
10215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
102165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
102175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
102185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback_2.WaitForResult());
102195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans_2->GetResponseInfo();
102205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
102215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(response->auth_challenge.get() == NULL);
102225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restart with auth. Tunnel should work and response received.
102245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_3;
102255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans_2->RestartWithAuth(
102265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback_3.callback());
102275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
102285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback_3.WaitForResult());
102295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After all that work, these two lines (or actually, just the scheme) are
102315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // what this test is all about. Make sure it happens correctly.
102325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("https", request_url.scheme());
102335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com", request_url.host());
102345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
102362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
102372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
102382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
102395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
102405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that if we cancel the transaction as the connection is completing, that
102425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// everything tears down correctly.
102437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
102445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setup everything about the connection to complete synchronously, so that
102455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // after calling HttpNetworkTransaction::Start, the only thing we're waiting
102465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for is the callback from the HttpStreamRequest.
102475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Then cancel the transaction.
102485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that we don't crash.
102495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(SYNCHRONOUS, OK);
102505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
102515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
102525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, "hello world"),
102535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
102545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
102555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
102575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
102585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
102595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
102605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->set_synchronous_mode(true);
102628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
102635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
102641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
102655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
102675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.set_connect_data(mock_connect);
10268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
102695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
102715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
102735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), log.bound());
102745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
102755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();  // Cancel the transaction here.
102765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1027790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
102785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
102795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Test that if a transaction is cancelled after receiving the headers, the
10281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// stream is drained properly and added back to the socket pool.  The main
10282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// purpose of this test is to make sure that an HttpStreamParser can be read
10283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// from after the HttpNetworkTransaction and the objects it owns have been
10284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// deleted.
10285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// See http://crbug.com/368418
10286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
10287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MockRead data_reads[] = {
10288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
10289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockRead(ASYNC, "Content-Length: 2\r\n"),
10290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
10291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockRead(ASYNC, "1"),
10292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // 2 async reads are necessary to trigger a ReadResponseBody call after the
10293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // HttpNetworkTransaction has been deleted.
10294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockRead(ASYNC, "2"),
10295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_IO_PENDING),  // Should never read this.
10296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  };
10297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
10299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  {
10303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    HttpRequestInfo request;
10304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    request.method = "GET";
10305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    request.url = GURL("http://www.google.com/");
10306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    request.load_flags = 0;
10307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
103081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
10309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    TestCompletionCallback callback;
10310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int rv = trans.Start(&request, callback.callback(), BoundNetLog());
10312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
10313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    callback.WaitForResult();
10314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const HttpResponseInfo* response = trans.GetResponseInfo();
10316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
10317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_TRUE(response->headers.get() != NULL);
10318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // The transaction and HttpRequestInfo are deleted.
10321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
10322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Let the HttpResponseBodyDrainer drain the socket.
10324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
10325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Socket should now be idle, waiting to be reused.
103271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
10328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
10329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
103305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a basic GET request through a proxy.
103317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ProxyGet) {
10332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
103332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
103345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
10335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
10336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
103375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
103395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
103405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
103415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
103435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
103445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
103455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
103465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
103475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
103495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
103505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
103515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
103525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
103535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
103545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
103565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
10357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
103585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
103605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10363116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  BeforeProxyHeadersSentHandler proxy_headers_handler;
10364116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  trans->SetBeforeProxyHeadersSentCallback(
10365116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
10366116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::Unretained(&proxy_headers_handler)));
103675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
103695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
103705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
103725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
103735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
103755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
103765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
103785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
103795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
103805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_proxy);
10381f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(
10382f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
10383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
10384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
103855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
103862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
103872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
103882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
103892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
103902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
103915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
103925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a basic HTTPS GET request through a proxy.
103947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
10395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
103962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
103975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
10398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
10399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
104005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
104025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
104035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
104045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
104065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
104075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
104085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
104095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
104105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
104125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
104135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
104145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
104155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
104175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
104185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
104205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
104215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
104225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
104235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
104245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
104265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
10427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
104285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
10429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
104305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
104325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10434868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
104355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
104375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
104385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
104405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
104415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
104425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
104435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
104445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
104455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
104465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
104475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
104485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
104495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
104505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
104525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
104535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
104555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
104565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
104575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
104585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_proxy);
10459f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(
10460f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
104612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
104622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
104632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
104642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
104652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
104665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
104675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a basic HTTPS GET request through a proxy, but the server hangs up
104695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// while establishing the tunnel.
104707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
10471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
104725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
10473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
10474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
104755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
104775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
104785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
104795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
104815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
104825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
104835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
104845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
104855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
104875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
104885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
104895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
104905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
104925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
104935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
104945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),  // EOF
104955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
104965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
104985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
10499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
105005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
10501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
105025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
105045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10506868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
105075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
105095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
105105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
105125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
105135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
105145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
105155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
105165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
105175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
105185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
105195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
105205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
105215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
105225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
105235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test for crbug.com/55424.
105257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
1052690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
1052790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
105285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
105295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
105317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
105325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
105335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
105345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data),
105355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
105365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
105375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
105395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
105405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
105415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
10542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
105435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
105457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
10546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
105475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
105495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up an initial SpdySession in the pool to reuse.
105515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair host_port_pair("www.google.com", 443);
1055290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
10553e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                     PRIVACY_MODE_DISABLED);
10554ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<SpdySession> spdy_session =
105557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      CreateInsecureSpdySession(session, key, BoundNetLog());
105565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
105585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
105595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
105605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
105615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is the important line that marks this as a preconnect.
105635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
105645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10566868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
105675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestCompletionCallback callback;
105695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
105705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
105715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
105725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
105735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Given a net error, cause that error to be returned from the first Write()
105755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// call and verify that the HttpTransaction fails with that error.
105767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
10577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int error, IoMode mode) {
105785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestInfo request_info;
105795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.url = GURL("https://www.example.com/");
105805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.method = "GET";
105815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.load_flags = net::LOAD_NORMAL;
105825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data(mode, OK);
105845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::MockWrite data_writes[] = {
105855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::MockWrite(mode, error),
105865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
105875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data(NULL, 0,
105885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     data_writes, arraysize(data_writes));
10589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
10590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
105915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
105932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10594868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
105955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
105975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
105985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == net::ERR_IO_PENDING)
105995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
106005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(error, rv);
106015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
106025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
106045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Just check a grab bag of cert errors.
106055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kErrors[] = {
106065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ERR_CERT_COMMON_NAME_INVALID,
106075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ERR_CERT_AUTHORITY_INVALID,
106085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ERR_CERT_DATE_INVALID,
106095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
106105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kErrors); i++) {
106115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckErrorIsPassedBack(kErrors[i], ASYNC);
106125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
106135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
106145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
106155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure that a client certificate is removed from the SSL client auth
106175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cache when:
106185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  1) No proxy is involved.
106195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  2) TLS False Start is disabled.
106205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  3) The initial TLS handshake requests a client certificate.
106215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  4) The client supplies an invalid/unacceptable certificate.
106227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
106235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ClientAuthCertCache_Direct_NoFalseStart) {
106245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestInfo request_info;
106255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.url = GURL("https://www.example.com/");
106265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.method = "GET";
106275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.load_flags = net::LOAD_NORMAL;
106285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
106305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cert_request->host_and_port = HostPortPair("www.example.com", 443);
106315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data1 contains the data for the first SSL handshake. When a
106335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CertificateRequest is received for the first time, the handshake will
106345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be aborted to allow the caller to provide a certificate.
106355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
106365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data1.cert_request_info = cert_request.get();
10637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
106385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
106405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data2 contains the data for the second SSL handshake. When TLS
106425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // False Start is not being used, the result of the SSL handshake will be
106435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // returned as part of the SSLClientSocket::Connect() call. This test
106445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // matches the result of a server sending a handshake_failure alert,
106455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // rather than a Finished message, because it requires a client
106465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate and none was supplied.
106475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
106485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data2.cert_request_info = cert_request.get();
10649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
106505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
10651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
106525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data3 contains the data for the third SSL handshake. When a
106545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection to a server fails during an SSL handshake,
106555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
106565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection was attempted with TLSv1.1. This is transparent to the caller
106575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the HttpNetworkTransaction. Because this test failure is due to
106585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // requiring a client certificate, this fallback handshake should also
106595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fail.
106605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
106615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data3.cert_request_info = cert_request.get();
10662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
106635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
10664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
106655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data4 contains the data for the fourth SSL handshake. When a
106675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection to a server fails during an SSL handshake,
106685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
106695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection was attempted with TLSv1. This is transparent to the caller
106705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the HttpNetworkTransaction. Because this test failure is due to
106715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // requiring a client certificate, this fallback handshake should also
106725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fail.
106735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
106745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data4.cert_request_info = cert_request.get();
10675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
106765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
10677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data4);
106785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10679868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Need one more if TLSv1.2 is enabled.
10680868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ssl_data5.cert_request_info = cert_request.get();
10682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10683868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10684868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data5);
10685868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
106872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10688868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
106895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Begin the SSL handshake with the peer. This consumes ssl_data1.
106915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
106925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
106935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_IO_PENDING, rv);
106945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the SSL handshake, which should abort due to requiring a
106965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // client certificate.
106975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
106985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
106995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Indicate that no certificate should be supplied. From the perspective
107015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of SSLClientCertCache, NULL is just as meaningful as a real
107025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate, so this is the same as supply a
107035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // legitimate-but-unacceptable certificate.
107045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithCertificate(NULL, callback.callback());
107055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_IO_PENDING, rv);
107065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure the certificate was added to the client auth cache before
107085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // allowing the connection to continue restarting.
107095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> client_cert;
107105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
107115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      HostPortPair("www.example.com", 443), &client_cert));
107125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(NULL, client_cert.get());
107135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restart the handshake. This will consume ssl_data2, which fails, and
107155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // then consume ssl_data3 and ssl_data4, both of which should also fail.
107165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The result code is checked against what ssl_data4 should return.
107175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
107185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
107195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that the client certificate is removed from the cache on a
107215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // handshake failure.
107225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
107235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      HostPortPair("www.example.com", 443), &client_cert));
107245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
107255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure that a client certificate is removed from the SSL client auth
107275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cache when:
107285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  1) No proxy is involved.
107295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  2) TLS False Start is enabled.
107305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  3) The initial TLS handshake requests a client certificate.
107315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  4) The client supplies an invalid/unacceptable certificate.
107327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
107335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ClientAuthCertCache_Direct_FalseStart) {
107345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestInfo request_info;
107355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.url = GURL("https://www.example.com/");
107365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.method = "GET";
107375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.load_flags = net::LOAD_NORMAL;
107385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
107405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cert_request->host_and_port = HostPortPair("www.example.com", 443);
107415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When TLS False Start is used, SSLClientSocket::Connect() calls will
107435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // return successfully after reading up to the peer's Certificate message.
107445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is to allow the caller to call SSLClientSocket::Write(), which can
107455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // enqueue application data to be sent in the same packet as the
107465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ChangeCipherSpec and Finished messages.
107475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The actual handshake will be finished when SSLClientSocket::Read() is
107485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called, which expects to process the peer's ChangeCipherSpec and
107495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finished messages. If there was an error negotiating with the peer,
107505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // such as due to the peer requiring a client certificate when none was
107515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // supplied, the alert sent by the peer won't be processed until Read() is
107525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called.
107535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Like the non-False Start case, when a client certificate is requested by
107555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the peer, the handshake is aborted during the Connect() call.
107565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data1 represents the initial SSL handshake with the peer.
107575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
107585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data1.cert_request_info = cert_request.get();
10759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
107605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
107625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When a client certificate is supplied, Connect() will not be aborted
107645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the peer requests the certificate. Instead, the handshake will
107655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // artificially succeed, allowing the caller to write the HTTP request to
107665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the socket. The handshake messages are not processed until Read() is
107675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called, which then detects that the handshake was aborted, due to the
107685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // peer sending a handshake_failure because it requires a client
107695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate.
107705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
107715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data2.cert_request_info = cert_request.get();
10772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
107735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::MockRead data2_reads[] = {
107745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
107755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
107765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data2(
107775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data2_reads, arraysize(data2_reads), NULL, 0);
10778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
107795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
107815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the data for the SSL handshake once the TLSv1.1 connection falls back to
107825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TLSv1. It has the same behaviour as [ssl_]data2.
107835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
107845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data3.cert_request_info = cert_request.get();
10785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
107865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data3(
107875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data2_reads, arraysize(data2_reads), NULL, 0);
10788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
107895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
107915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
107925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
107935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data4.cert_request_info = cert_request.get();
10794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
107955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data4(
107965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data2_reads, arraysize(data2_reads), NULL, 0);
10797c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data4);
107985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10799868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Need one more if TLSv1.2 is enabled.
10800868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10801868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ssl_data5.cert_request_info = cert_request.get();
10802868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10803868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net::StaticSocketDataProvider data5(
10804868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      data2_reads, arraysize(data2_reads), NULL, 0);
10805868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data5);
10806868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10807c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
108082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10809868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
108105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Begin the initial SSL handshake.
108125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
108135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
108145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_IO_PENDING, rv);
108155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the SSL handshake, which should abort due to requiring a
108175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // client certificate.
108185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
108195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
108205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Indicate that no certificate should be supplied. From the perspective
108225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of SSLClientCertCache, NULL is just as meaningful as a real
108235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate, so this is the same as supply a
108245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // legitimate-but-unacceptable certificate.
108255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithCertificate(NULL, callback.callback());
108265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_IO_PENDING, rv);
108275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure the certificate was added to the client auth cache before
108295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // allowing the connection to continue restarting.
108305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> client_cert;
108315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
108325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      HostPortPair("www.example.com", 443), &client_cert));
108335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(NULL, client_cert.get());
108345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restart the handshake. This will consume ssl_data2, which fails, and
108365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // then consume ssl_data3 and ssl_data4, both of which should also fail.
108375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The result code is checked against what ssl_data4 should return.
108385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
108395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
108405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that the client certificate is removed from the cache on a
108425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // handshake failure.
108435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
108445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      HostPortPair("www.example.com", 443), &client_cert));
108455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
108465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure that a client certificate is removed from the SSL client auth
108485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cache when:
108495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  1) An HTTPS proxy is involved.
108505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  3) The HTTPS proxy requests a client certificate.
108515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  4) The client supplies an invalid/unacceptable certificate for the
108525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     proxy.
108535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The test is repeated twice, first for connecting to an HTTPS endpoint,
108545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// then for connecting to an HTTP endpoint.
108557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
10856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
108575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://proxy:70"));
108585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
10859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
108605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
108625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cert_request->host_and_port = HostPortPair("proxy", 70);
108635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
108655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data[1-3]. Rather than represending the endpoint
108665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (www.example.com:443), they represent failures with the HTTPS proxy
108675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (proxy:70).
108685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
108695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data1.cert_request_info = cert_request.get();
10870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
108715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
108735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
108755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data2.cert_request_info = cert_request.get();
10876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
108775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
10878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
108795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
108815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0
108825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
108835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data3.cert_request_info = cert_request.get();
10884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
108855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
10886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
108875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
108885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestInfo requests[2];
108905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[0].url = GURL("https://www.example.com/");
108915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[0].method = "GET";
108925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[0].load_flags = net::LOAD_NORMAL;
108935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[1].url = GURL("http://www.example.com/");
108955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[1].method = "GET";
108965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[1].load_flags = net::LOAD_NORMAL;
108975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(requests); ++i) {
10899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->ResetNextMockIndexes();
10900c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
109015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpNetworkTransaction> trans(
10902868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
109035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Begin the SSL handshake with the proxy.
109055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
109065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(
109075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &requests[i], callback.callback(), net::BoundNetLog());
109085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(net::ERR_IO_PENDING, rv);
109095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Complete the SSL handshake, which should abort due to requiring a
109115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // client certificate.
109125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
109135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
109145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Indicate that no certificate should be supplied. From the perspective
109165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // of SSLClientCertCache, NULL is just as meaningful as a real
109175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // certificate, so this is the same as supply a
109185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // legitimate-but-unacceptable certificate.
109195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithCertificate(NULL, callback.callback());
109205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(net::ERR_IO_PENDING, rv);
109215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ensure the certificate was added to the client auth cache before
109235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // allowing the connection to continue restarting.
109245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<X509Certificate> client_cert;
109255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
109265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        HostPortPair("proxy", 70), &client_cert));
109275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(NULL, client_cert.get());
109285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ensure the certificate was NOT cached for the endpoint. This only
109295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // applies to HTTPS requests, but is fine to check for HTTP requests.
109305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
109315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        HostPortPair("www.example.com", 443), &client_cert));
109325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Restart the handshake. This will consume ssl_data2, which fails, and
109345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // then consume ssl_data3, which should also fail. The result code is
109355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // checked against what ssl_data3 should return.
109365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
109375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
109385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Now that the new handshake has failed, ensure that the client
109405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // certificate was removed from the client auth cache.
109415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
109425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        HostPortPair("proxy", 70), &client_cert));
109435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
109445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        HostPortPair("www.example.com", 443), &client_cert));
109455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
109465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
109475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Unlike TEST/TEST_F, which are macros that expand to further macros,
109497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// TEST_P is a macro that expands directly to code that stringizes the
109507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// arguments. As a result, macros passed as parameters (such as prefix
109517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// or test_case_name) will not be expanded by the preprocessor. To
109527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// work around this, indirect the macro for TEST_P, so that the
109537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// pre-processor will expand macros such as MAYBE_test_name before
109547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// instantiating the test.
109557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#define WRAPPED_TEST_P(test_case_name, test_name) \
109567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TEST_P(test_case_name, test_name)
109577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
109585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Times out on Win7 dbg(2) bot. http://crbug.com/124776
109595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
109605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
109615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
109625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
109635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
109647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
10965cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
10966cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
109675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a special HttpNetworkSession with a MockCachingHostResolver.
10969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver.reset(new MockCachingHostResolver());
10970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
109715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
109725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pool_peer.DisableDomainAuthenticationVerification();
109735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
109757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
10976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
109775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1097890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host1_req(
1097990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
1098090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host2_req(
1098190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
109825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
109835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host1_req, 1),
109845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host2_req, 4),
109855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
109867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp(
109877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
109887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp_body(
109897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
109907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp(
109917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
109927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp_body(
109937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, true));
109945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
109955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp, 2),
109965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp_body, 3),
109975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp, 5),
109985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp_body, 6),
109995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 7),
110005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
110015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip;
110035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
110045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint peer_addr = IPEndPoint(ip, 443);
110055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect(ASYNC, OK, peer_addr);
110065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
110075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      connect,
110085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
110095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
11010c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
110115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
110135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
110145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
110155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL("https://www.google.com/");
110165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11017868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
110185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
110205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
110215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
110225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans1.GetResponseInfo();
110245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11025868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
110265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
110275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
110295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
110305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
110315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preload www.gmail.com into HostCache.
110335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair host_port("www.gmail.com", 443);
110345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostResolver::RequestInfo resolve_info(host_port);
110355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList ignored;
110363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  rv = session_deps_.host_resolver->Resolve(resolve_info,
110373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            DEFAULT_PRIORITY,
110383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            &ignored,
110393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            callback.callback(),
110403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            NULL,
110413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            BoundNetLog());
110425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
110435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
110445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
110455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
110475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
110485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL("https://www.gmail.com/");
110495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11050868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
110515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
110535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
110545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
110555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans2.GetResponseInfo();
110575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11058868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
110595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
110605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
110615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
110625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
110635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
110645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
110655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef MAYBE_UseIPConnectionPooling
110665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
11068cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
11069cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
110705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a special HttpNetworkSession with a MockCachingHostResolver.
11072c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver.reset(new MockCachingHostResolver());
11073c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
110745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
110755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pool_peer.DisableDomainAuthenticationVerification();
110765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
110787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
11079c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
110805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1108190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host1_req(
1108290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
1108390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host2_req(
1108490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
110855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
110865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host1_req, 1),
110875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host2_req, 4),
110885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
110897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp(
110907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
110917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp_body(
110927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
110937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp(
110947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
110957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp_body(
110967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, true));
110975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
110985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp, 2),
110995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp_body, 3),
111005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp, 5),
111015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp_body, 6),
111025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 7),
111035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
111045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip;
111065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
111075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint peer_addr = IPEndPoint(ip, 443);
111085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect(ASYNC, OK, peer_addr);
111095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
111105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      connect,
111115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
111125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
11113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
111145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
111165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
111175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
111185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL("https://www.google.com/");
111195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
111215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
111235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
111245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
111255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans1.GetResponseInfo();
111275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
111295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
111305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
111325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
111335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
111345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
111365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
111375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL("https://www.gmail.com/");
111385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
111405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
111425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
111435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
111445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans2.GetResponseInfo();
111465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
111485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
111495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
111505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
111515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
111525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
111535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
111545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OneTimeCachingHostResolver : public net::HostResolver {
111565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
111575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
111585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : host_port_(host_port) {}
111595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~OneTimeCachingHostResolver() {}
111605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
111625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HostResolver methods:
111645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int Resolve(const RequestInfo& info,
111653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                      RequestPriority priority,
111665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      AddressList* addresses,
111675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const CompletionCallback& callback,
111685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      RequestHandle* out_req,
111695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const BoundNetLog& net_log) OVERRIDE {
111705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return host_resolver_.Resolve(
111713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        info, priority, addresses, callback, out_req, net_log);
111725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
111735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int ResolveFromCache(const RequestInfo& info,
111755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               AddressList* addresses,
111765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const BoundNetLog& net_log) OVERRIDE {
111775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
111785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv == OK && info.host_port_pair().Equals(host_port_))
111795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_resolver_.GetHostCache()->clear();
111805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
111815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
111825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CancelRequest(RequestHandle req) OVERRIDE {
111845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_resolver_.CancelRequest(req);
111855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
111865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockCachingHostResolver* GetMockHostResolver() {
111885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &host_resolver_;
111895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
111905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
111925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockCachingHostResolver host_resolver_;
111935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HostPortPair host_port_;
111945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
111955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Times out on Win7 dbg(2) bot. http://crbug.com/124776
111975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
11198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
112005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
11201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    UseIPConnectionPoolingWithHostCacheExpiration
112035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
112047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)WRAPPED_TEST_P(HttpNetworkTransactionTest,
112057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)               MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
112067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
112077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// prefix doesn't work with parametrized tests).
112087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
112097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return;
1121023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#else
11211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
11212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
112135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
112155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
112162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpNetworkSession::Params params =
11217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::CreateSessionParams(&session_deps_);
112185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.host_resolver = &host_resolver;
11219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
112205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
112215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pool_peer.DisableDomainAuthenticationVerification();
112225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
112247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
11225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
112265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1122790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host1_req(
1122890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
1122990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host2_req(
1123090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
112315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
112325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host1_req, 1),
112335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host2_req, 4),
112345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
112357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp(
112367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
112377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp_body(
112387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
112397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp(
112407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
112417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp_body(
112427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, true));
112435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
112445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp, 2),
112455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp_body, 3),
112465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp, 5),
112475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp_body, 6),
112485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 7),
112495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
112505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip;
112525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
112535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint peer_addr = IPEndPoint(ip, 443);
112545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect(ASYNC, OK, peer_addr);
112555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
112565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      connect,
112575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
112585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
11259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
112605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
112625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
112635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
112645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL("https://www.google.com/");
112655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
112675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
112695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
112705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
112715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans1.GetResponseInfo();
112735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
112755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
112765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
112785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
112795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
112805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preload cache entries into HostCache.
112825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
112835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList ignored;
112843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  rv = host_resolver.Resolve(resolve_info,
112853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             DEFAULT_PRIORITY,
112863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             &ignored,
112873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             callback.callback(),
112883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             NULL,
112893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             BoundNetLog());
112905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
112915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
112925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
112935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
112955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
112965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL("https://www.gmail.com/");
112975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
112995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
113015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
113025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
113035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans2.GetResponseInfo();
113055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
113075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
113085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
113095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
113105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
113115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
1131223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#endif
113135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
113145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
113155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
113175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string https_url = "https://www.google.com/";
113185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string http_url = "http://www.google.com:443/";
113195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTPS URL
1132190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(
1132290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
113235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes1[] = {
113255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req1, 0),
113265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
113275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
113297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
113305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads1[] = {
113315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp1, 1),
113325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body1, 2),
113335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 3)
113345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
113355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data1(
113375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1, reads1, arraysize(reads1),
113385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writes1, arraysize(writes1));
113395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect_data1(ASYNC, OK);
113405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1.set_connect_data(connect_data1);
113415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HTTP GET for the HTTP URL
113435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes2[] = {
113445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, 4,
113455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "GET / HTTP/1.1\r\n"
113465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com:443\r\n"
113475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
113485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
113495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads2[] = {
113515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
113525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 6, "hello"),
113535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 7, OK),
113545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
113555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data2(
113575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1, reads2, arraysize(reads2),
113585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writes2, arraysize(writes2));
113595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
113617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
11362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
11364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
113655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
113675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first transaction to set up the SpdySession
113695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
113705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
113715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL(https_url);
113725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(LOWEST, session.get());
113745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
113755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
113765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
1137790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
113785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
113805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
113815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, start the HTTP request
113835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
113845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
113855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL(http_url);
113865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11387868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
113885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
113895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
113905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1139190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
113925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
113945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
113955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
113965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
113985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string https_url = "https://www.google.com/";
113995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string http_url = "http://www.google.com:443/";
114005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTPS URL (through CONNECT tunnel)
114023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
114033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                LOWEST));
1140490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(
1140590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
114067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_req1(
114077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
11408c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
11409c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
11410116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SpdyHeaderBlock req2_block;
11411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  req2_block[spdy_util_.GetMethodKey()] = "GET";
11412116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  req2_block[spdy_util_.GetPathKey()] =
11413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      spdy_util_.is_spdy2() ? http_url.c_str() : "/";
11414116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  req2_block[spdy_util_.GetHostKey()] = "www.google.com:443";
11415116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  req2_block[spdy_util_.GetSchemeKey()] = "http";
11416116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  spdy_util_.MaybeAddVersionHeader(&req2_block);
11417c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_ptr<SpdyFrame> req2(
11418116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
114195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes1[] = {
114215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*connect, 0),
114225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*wrapped_req1, 2),
114235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2, 5),
114245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
114255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp(
114277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
114287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
114297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
114307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_resp1(
114317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
114327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body1(
114337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
114347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
114357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
114365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads1[] = {
114375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_resp, 1),
114385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_resp1, 3),
114395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body1, 4),
114405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2, 6),
114415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2, 7),
114425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 8)
114435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
114445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeterministicSocketData data1(reads1, arraysize(reads1),
114465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                writes1, arraysize(writes1));
114475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect_data1(ASYNC, OK);
114485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1.set_connect_data(connect_data1);
114495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
114512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
114522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog log;
11453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &log;
114545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
114557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl1.SetNextProto(GetParam());
11456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
114575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
114587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
11459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
114615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
11463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
114645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first transaction to set up the SpdySession
114665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
114675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
114685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL(https_url);
114695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11470868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(LOWEST, session.get());
114715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
114725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
114735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
1147490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
114755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1.RunFor(4);
114765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
114785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
114795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
114812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
114822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info1,
114832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
114842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
114855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, start the HTTP request
114865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
114875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
114885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL(http_url);
114895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
114915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
114925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
114935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1149490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
114955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1.RunFor(3);
114965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
114985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
114992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
115002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
115012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
115022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The established SPDY sessions is considered reused by the HTTP request.
115032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReusedWithPac(load_timing_info2);
115042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // HTTP requests over a SPDY session should have a different connection
115052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // socket_log_id than requests over a tunnel.
115062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
115075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
115085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
11510cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.force_spdy_always = true;
115115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string https_url = "https://www.google.com/";
115125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string http_url = "http://www.google.com:443/";
115135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTPS URL
1151590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(
1151690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
115175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for the HTTP URL
1151890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
1151990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
115205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
115225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req1, 1),
115235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2, 4),
115245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
115255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
115277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
115287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
115297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
115305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
115315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp1, 2),
115325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body1, 3),
115335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2, 5),
115345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2, 6),
115355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 7)
115365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
115375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data(reads, arraysize(reads),
115395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         writes, arraysize(writes));
115405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
115427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
11543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
115455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
115475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first transaction to set up the SpdySession
115495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
115505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
115515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL(https_url);
115525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(LOWEST, session.get());
115545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
115555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
115565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
1155790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
115585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
115605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
115615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, start the HTTP request
115635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
115645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
115655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL(http_url);
115665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11567868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
115685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
115695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
115705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1157190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
115725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
115745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
115755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
115765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that in the case where we have a SPDY session to a SPDY proxy
115785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that we do not pool other origins that resolve to the same IP when
115795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the certificate does not match the new origin.
115805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/134690
115817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
115825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string url1 = "http://www.google.com/";
115835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string url2 = "https://mail.google.com/";
115845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string ip_addr = "1.2.3.4";
115855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTP URL (through SPDY proxy)
115877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> headers(
115887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
11589116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<SpdyFrame> req1(
11590116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
115915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes1[] = {
115935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req1, 0),
115945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
115955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
115977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
115985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads1[] = {
115995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp1, 1),
116005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body1, 2),
116015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK, 3) // EOF
116025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
116035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeterministicSocketData> data1(
116055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new DeterministicSocketData(reads1, arraysize(reads1),
116065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  writes1, arraysize(writes1)));
116075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip;
116085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
116095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint peer_addr = IPEndPoint(ip, 443);
116105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect_data1(ASYNC, OK, peer_addr);
116115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1->set_connect_data(connect_data1);
116125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTPS URL (direct)
1161490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
1161590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
116165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes2[] = {
116185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2, 0),
116195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
116205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
116227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
116235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads2[] = {
116245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2, 1),
116255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2, 2),
116265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK, 3) // EOF
116275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
116285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeterministicSocketData> data2(
116305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new DeterministicSocketData(reads2, arraysize(reads2),
116315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  writes2, arraysize(writes2)));
116325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect_data2(ASYNC, OK);
116335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data2->set_connect_data(connect_data2);
116345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a proxy config that sends HTTP requests to a proxy, and
116365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // all others direct.
116375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig proxy_config;
116385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
116395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingProxyResolver* capturing_proxy_resolver =
116405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new CapturingProxyResolver();
11641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(new ProxyService(
116425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
116435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL));
116445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load a valid cert.  Note, that this does not need to
116465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be valid for proxy because the MockSSLClientSocket does
116475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not actually verify it.  But SpdySession will use this
116485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to see if it is valid for the new origin
116492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath certs_dir = GetTestCertsDirectory();
116505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> server_cert(
116515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ImportCertFromFile(certs_dir, "ok_cert.pem"));
116521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get());
116535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
116557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl1.SetNextProto(GetParam());
116565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl1.cert = server_cert;
11657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data1.get());
116605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
116627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
11663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data2.get());
116665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver.reset(new MockCachingHostResolver());
11668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
116705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
11672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
116735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first transaction to set up the SpdySession
116755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
116765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
116775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL(url1);
116785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11679868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(LOWEST, session.get());
116805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
116815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING,
116825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
116835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1->RunFor(3);
116845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(callback1.have_result());
116865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
116875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
116885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, start the HTTP request
116905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
116915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
116925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL(url2);
116935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11694868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
116955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
116965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
116975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1169890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
116995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data2->RunFor(3);
117005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
117015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(callback2.have_result());
117025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
117035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
117045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
117055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// error) in SPDY session, removes the socket from pool and closes the SPDY
11708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// session. Verify that new url's from the same HttpNetworkSession (and a new
11709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// SpdySession) do work. http://crbug.com/224701
117107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
11711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const std::string https_url = "https://www.google.com/";
11712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockRead reads1[] = {
11714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
11716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DeterministicSocketData> data1(
11718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  data1->SetStop(1);
11720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1172190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
1172290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
11723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockWrite writes2[] = {
11724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CreateMockWrite(*req2, 0),
11725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
11726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
117277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
117287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
11729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockRead reads2[] = {
11730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CreateMockRead(*resp2, 1),
11731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CreateMockRead(*body2, 2),
11732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, OK, 3)  // EOF
11733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
11734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DeterministicSocketData> data2(
11736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new DeterministicSocketData(reads2, arraysize(reads2),
11737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  writes2, arraysize(writes2)));
11738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SSLSocketDataProvider ssl1(ASYNC, OK);
117407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl1.SetNextProto(GetParam());
11741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data1.get());
11744c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
117467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
11747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data2.get());
11750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
11752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
11753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Start the first transaction to set up the SpdySession and verify that
11755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // connection was closed.
11756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HttpRequestInfo request1;
11757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request1.method = "GET";
11758c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request1.url = GURL(https_url);
11759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request1.load_flags = 0;
11760868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(MEDIUM, session.get());
11761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback1;
11762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
11763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
1176490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
11765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Now, start the second request and make sure it succeeds.
11768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HttpRequestInfo request2;
11769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request2.method = "GET";
11770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request2.url = GURL(https_url);
11771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request2.load_flags = 0;
11772868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
11773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback2;
11774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
11775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1177690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
11777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  data2->RunFor(3);
11778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(callback2.have_result());
11780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
11781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11782c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
11783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
117847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
11785cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
11786a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_group(
11787a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11788a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_pool(
11789a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11790a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11791a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Use two different hosts with different IPs so they don't get pooled.
11792a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11793a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11794a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11795a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11796a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SSLSocketDataProvider ssl1(ASYNC, OK);
117977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl1.SetNextProto(GetParam());
11798a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
117997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
11800a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11801a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11802a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1180390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
11804a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11805a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockWrite spdy1_writes[] = {
11806a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockWrite(*host1_req, 1),
11807a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
118087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp(
118097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
118107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp_body(
118117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
11812a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockRead spdy1_reads[] = {
11813a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockRead(*host1_resp, 2),
11814a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockRead(*host1_resp_body, 3),
11815a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 4),
11816a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
11817a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11818a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<OrderedSocketData> spdy1_data(
11819a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      new OrderedSocketData(
11820a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          spdy1_reads, arraysize(spdy1_reads),
11821a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          spdy1_writes, arraysize(spdy1_writes)));
11822a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11823a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1182490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
11825a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11826a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockWrite spdy2_writes[] = {
11827a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockWrite(*host2_req, 1),
11828a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
118297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp(
118307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
118317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp_body(
118327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
11833a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockRead spdy2_reads[] = {
11834a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockRead(*host2_resp, 2),
11835a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockRead(*host2_resp_body, 3),
11836a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 4),
11837a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
11838a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11839a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<OrderedSocketData> spdy2_data(
11840a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      new OrderedSocketData(
11841a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          spdy2_reads, arraysize(spdy2_reads),
11842a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          spdy2_writes, arraysize(spdy2_writes)));
11843a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11844a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11845a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockWrite http_write[] = {
11846a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
11847a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)              "Host: www.a.com\r\n"
11848a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
11849a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
11850a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11851a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockRead http_read[] = {
11852a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
11853a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11854a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead("Content-Length: 6\r\n\r\n"),
11855a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead("hello!"),
11856a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
11857a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11858a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                     http_write, arraysize(http_write));
11859a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11860a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11861a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HostPortPair host_port_pair_a("www.a.com", 443);
1186290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey spdy_session_key_a(
11863e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
11864a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
118657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11866a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11867a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  TestCompletionCallback callback;
11868a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HttpRequestInfo request1;
11869a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request1.method = "GET";
11870a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request1.url = GURL("https://www.a.com/");
11871a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request1.load_flags = 0;
11872a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans(
11873868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11874a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11875a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11876a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11877a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
11878a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11879a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
11880a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
11881868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
11882a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11883a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
11884a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
11885a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11886a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  std::string response_data;
11887a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11888a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("hello!", response_data);
11889a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  trans.reset();
11890a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(
118917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11892a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11893a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HostPortPair host_port_pair_b("www.b.com", 443);
1189490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey spdy_session_key_b(
11895e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
11896a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
118977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11898a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HttpRequestInfo request2;
11899a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request2.method = "GET";
11900a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request2.url = GURL("https://www.b.com/");
11901a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request2.load_flags = 0;
11902868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11903a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11904a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11905a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11906a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
11907a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11908a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  response = trans->GetResponseInfo();
11909a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
11910868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
11911a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11912a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
11913a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
11914a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11915a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("hello!", response_data);
11916a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
119177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11918a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(
119197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11920a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11921a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HostPortPair host_port_pair_a1("www.a.com", 80);
1192290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey spdy_session_key_a1(
11923e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
11924a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
119257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
11926a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HttpRequestInfo request3;
11927a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request3.method = "GET";
11928a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request3.url = GURL("http://www.a.com/");
11929a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request3.load_flags = 0;
11930868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11931a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11932a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11933a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11934a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
11935a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11936a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  response = trans->GetResponseInfo();
11937a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
11938868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
11939a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11940a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
11941a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(response->was_npn_negotiated);
11942a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11943a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("hello!", response_data);
11944a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
119457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11946a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
119477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11948a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
11949a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11950eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11951eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11952eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11953eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11954eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11955eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
119568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11957eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
119581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11959eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11960eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11961eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data;
11962eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  data.set_connect_data(mock_connect);
11963eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
11964eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11965eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
11966eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11967eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11968eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
11969eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11970eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
11971eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11972eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11973eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
11974eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11975eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // We don't care whether this succeeds or fails, but it shouldn't crash.
11976eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
11977eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  trans->GetFullRequestHeaders(&request_headers);
11978eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
11979eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11980eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11981eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11982eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11983eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11984eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11985eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
119868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11987eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
119881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11989eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11990eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11991eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data;
11992eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  data.set_connect_data(mock_connect);
11993eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
11994eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11995eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
11996eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11997eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11998eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
11999eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12000eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
12001eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12002eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12003eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
12004eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12005eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // We don't care whether this succeeds or fails, but it shouldn't crash.
12006eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
12007eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  trans->GetFullRequestHeaders(&request_headers);
12008eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
12009eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12010eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
12011eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
12012eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
12013eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
12014eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
12015eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
120168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12017eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
120181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12019eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12020eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
12021eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12022eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12023eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
12024eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
12025eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12026eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12027eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12028eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
12029eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
12030eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12031eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
12032eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12033eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12034eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
12035eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12036eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
12037eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12038eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12039eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
12040eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12041eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
12042eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12043eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.HasHeader("Host"));
12044eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
12045eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12046eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
12047eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
12048eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
12049eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
12050eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
12051eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
120528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12053eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
120541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12055eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12056eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
12057eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite(ASYNC, ERR_CONNECTION_RESET),
12058eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12059eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
12060eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
12061eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12062eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12063eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12064eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
12065eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
12066eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12067eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
12068eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12069eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12070eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
12071eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12072eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
12073eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12074eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12075eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
12076eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12077eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
12078eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12079eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.HasHeader("Host"));
12080eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
12081eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12082eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
12083eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
12084eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
12085eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
12086eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
12087eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
120888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12089eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
120901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12091eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12092eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
12093eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite("GET / HTTP/1.1\r\n"
12094eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Host: www.google.com\r\n"
12095eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Connection: keep-alive\r\n\r\n"),
12096eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12097eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
12098eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
12099eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
12103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
12104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
12106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
12109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
12111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
12114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
12116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.HasHeader("Host"));
12118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
12119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
12121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
12122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
12123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
12124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
12125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
121268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
121281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
12131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite("GET / HTTP/1.1\r\n"
12132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Host: www.google.com\r\n"
12133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Connection: keep-alive\r\n\r\n"),
12134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
12136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(ASYNC, ERR_CONNECTION_RESET),
12137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
12141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
12142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
12144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
12147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
12149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
12152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
12154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.HasHeader("Host"));
12156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
12157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
12159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
12160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
12161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
12162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
12163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.extra_headers.SetHeader("X-Foo", "bar");
12164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
121658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
121671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
12170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite("GET / HTTP/1.1\r\n"
12171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Host: www.google.com\r\n"
12172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Connection: keep-alive\r\n"
12173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "X-Foo: bar\r\n\r\n"),
12174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
12176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead("HTTP/1.1 200 OK\r\n"
12177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch             "Content-Length: 5\r\n\r\n"
12178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch             "hello"),
12179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(ASYNC, ERR_UNEXPECTED),
12180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
12184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
12185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
12187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
12190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
12192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(OK, rv);
12193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
12195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string foo;
12197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ("bar", foo);
12199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
12200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
122013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace {
122023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Fake HttpStreamBase that simply records calls to SetPriority().
122043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class FakeStream : public HttpStreamBase,
122053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   public base::SupportsWeakPtr<FakeStream> {
122063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
122073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  explicit FakeStream(RequestPriority priority) : priority_(priority) {}
122083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual ~FakeStream() {}
122093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RequestPriority priority() const { return priority_; }
122113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual int InitializeStream(const HttpRequestInfo* request_info,
122133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                               RequestPriority priority,
122143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                               const BoundNetLog& net_log,
122153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                               const CompletionCallback& callback) OVERRIDE {
122163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ERR_IO_PENDING;
122173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual int SendRequest(const HttpRequestHeaders& request_headers,
122203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          HttpResponseInfo* response,
122213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          const CompletionCallback& callback) OVERRIDE {
122223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ERR_UNEXPECTED;
122243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
122273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ERR_UNEXPECTED;
122293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
122323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                               const CompletionCallback& callback) OVERRIDE {
122333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ERR_UNEXPECTED;
122353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void Close(bool not_reusable) OVERRIDE {}
122383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool IsResponseBodyComplete() const OVERRIDE {
122403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
122423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool CanFindEndOfResponse() const OVERRIDE {
122453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
122463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool IsConnectionReused() const OVERRIDE {
122493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
122513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void SetConnectionReused() OVERRIDE {
122543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool IsConnectionReusable() const OVERRIDE {
122583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
122603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int64 GetTotalReceivedBytes() const OVERRIDE {
122635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ADD_FAILURE();
122645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return 0;
122655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
122665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
122673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool GetLoadTimingInfo(
122683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      LoadTimingInfo* load_timing_info) const OVERRIDE {
122693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
122713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
122743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void GetSSLCertRequestInfo(
122783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      SSLCertRequestInfo* cert_request_info) OVERRIDE {
122793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool IsSpdyHttpStream() const OVERRIDE {
122833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
122853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void Drain(HttpNetworkSession* session) OVERRIDE {
122883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void SetPriority(RequestPriority priority) OVERRIDE {
122923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    priority_ = priority;
122933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private:
122963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RequestPriority priority_;
122973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeStream);
122993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
123003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Fake HttpStreamRequest that simply records calls to SetPriority()
123023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// and vends FakeStreams with its current priority.
123033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class FakeStreamRequest : public HttpStreamRequest,
123043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          public base::SupportsWeakPtr<FakeStreamRequest> {
123053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
123063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeStreamRequest(RequestPriority priority,
123073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    HttpStreamRequest::Delegate* delegate)
123083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      : priority_(priority),
12309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        delegate_(delegate),
12310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        websocket_stream_create_helper_(NULL) {}
12311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  FakeStreamRequest(RequestPriority priority,
12313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    HttpStreamRequest::Delegate* delegate,
12314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    WebSocketHandshakeStreamBase::CreateHelper* create_helper)
12315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : priority_(priority),
12316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        delegate_(delegate),
12317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        websocket_stream_create_helper_(create_helper) {}
123183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual ~FakeStreamRequest() {}
123203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RequestPriority priority() const { return priority_; }
123223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const WebSocketHandshakeStreamBase::CreateHelper*
12324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  websocket_stream_create_helper() const {
12325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return websocket_stream_create_helper_;
12326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
12327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
123283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Create a new FakeStream and pass it to the request's
123293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // delegate. Returns a weak pointer to the FakeStream.
123303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStream> FinishStreamRequest() {
123313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FakeStream* fake_stream = new FakeStream(priority_);
123323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Do this before calling OnStreamReady() as OnStreamReady() may
123333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // immediately delete |fake_stream|.
123343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
123353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
123363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return weak_stream;
123373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual int RestartTunnelWithProxyAuth(
123403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const AuthCredentials& credentials) OVERRIDE {
123413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
123423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ERR_UNEXPECTED;
123433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual LoadState GetLoadState() const OVERRIDE {
123463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
123473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return LoadState();
123483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void SetPriority(RequestPriority priority) OVERRIDE {
123513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    priority_ = priority;
123523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool was_npn_negotiated() const OVERRIDE {
123553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
123563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual NextProto protocol_negotiated() const OVERRIDE {
123593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return kProtoUnknown;
123603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool using_spdy() const OVERRIDE {
123633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
123643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private:
123673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RequestPriority priority_;
123683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpStreamRequest::Delegate* const delegate_;
12369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
123703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
123723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
123733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Fake HttpStreamFactory that vends FakeStreamRequests.
123753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class FakeStreamFactory : public HttpStreamFactory {
123763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
123773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeStreamFactory() {}
123783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual ~FakeStreamFactory() {}
123793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Returns a WeakPtr<> to the last HttpStreamRequest returned by
123813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // RequestStream() (which may be NULL if it was destroyed already).
123823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStreamRequest> last_stream_request() {
123833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return last_stream_request_;
123843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual HttpStreamRequest* RequestStream(
123873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const HttpRequestInfo& info,
123883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      RequestPriority priority,
123893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const SSLConfig& server_ssl_config,
123903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const SSLConfig& proxy_ssl_config,
123913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpStreamRequest::Delegate* delegate,
123923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const BoundNetLog& net_log) OVERRIDE {
123933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
123943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    last_stream_request_ = fake_request->AsWeakPtr();
123953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return fake_request;
123963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
123993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const HttpRequestInfo& info,
124003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      RequestPriority priority,
124013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const SSLConfig& server_ssl_config,
124023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const SSLConfig& proxy_ssl_config,
124033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpStreamRequest::Delegate* delegate,
12404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      WebSocketHandshakeStreamBase::CreateHelper* create_helper,
124053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const BoundNetLog& net_log) OVERRIDE {
12406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FakeStreamRequest* fake_request =
12407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new FakeStreamRequest(priority, delegate, create_helper);
12408f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    last_stream_request_ = fake_request->AsWeakPtr();
12409f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return fake_request;
124103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
124113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void PreconnectStreams(int num_streams,
124133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                 const HttpRequestInfo& info,
124143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                 RequestPriority priority,
124153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                 const SSLConfig& server_ssl_config,
124163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                 const SSLConfig& proxy_ssl_config) OVERRIDE {
124173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
124183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
124193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE {
124213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
124223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return NULL;
124233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
124243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private:
124263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStreamRequest> last_stream_request_;
124273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
124293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
124303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// TODO(yhirano): Split this class out into a net/websockets file, if it is
12432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// worth doing.
12433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class FakeWebSocketStreamCreateHelper :
12434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      public WebSocketHandshakeStreamBase::CreateHelper {
12435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
12436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual WebSocketHandshakeStreamBase* CreateBasicStream(
12437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      scoped_ptr<ClientSocketHandle> connection,
12438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      bool using_proxy) OVERRIDE {
12439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NOTREACHED();
12440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return NULL;
12441f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
12442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual WebSocketHandshakeStreamBase* CreateSpdyStream(
12444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const base::WeakPtr<SpdySession>& session,
12445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      bool use_relative_url) OVERRIDE {
12446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NOTREACHED();
12447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return NULL;
12448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  };
12449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~FakeWebSocketStreamCreateHelper() {}
12451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual scoped_ptr<WebSocketStream> Upgrade() {
12453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NOTREACHED();
12454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return scoped_ptr<WebSocketStream>();
12455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
12456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
12457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
124583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}  // namespace
124593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Make sure that HttpNetworkTransaction passes on its priority to its
124613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// stream request on start.
124623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
124633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
124643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkSessionPeer peer(session);
124653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeStreamFactory* fake_factory = new FakeStreamFactory();
12466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
124673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  HttpNetworkTransaction trans(LOW, session.get());
124693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
124713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo request;
124733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback callback;
124743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
124753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            trans.Start(&request, callback.callback(), BoundNetLog()));
124763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStreamRequest> fake_request =
124783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      fake_factory->last_stream_request();
124793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_request != NULL);
124803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(LOW, fake_request->priority());
124813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
124823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Make sure that HttpNetworkTransaction passes on its priority
124843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// updates to its stream request.
124853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
124863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
124873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkSessionPeer peer(session);
124883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeStreamFactory* fake_factory = new FakeStreamFactory();
12489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
124903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  HttpNetworkTransaction trans(LOW, session.get());
124923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo request;
124943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback callback;
124953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
124963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            trans.Start(&request, callback.callback(), BoundNetLog()));
124973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStreamRequest> fake_request =
124993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      fake_factory->last_stream_request();
125003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_request != NULL);
125013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(LOW, fake_request->priority());
125023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  trans.SetPriority(LOWEST);
125043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_request != NULL);
125053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(LOWEST, fake_request->priority());
125063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
125073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Make sure that HttpNetworkTransaction passes on its priority
125093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// updates to its stream.
125103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
125113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
125123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkSessionPeer peer(session);
125133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeStreamFactory* fake_factory = new FakeStreamFactory();
12514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
125153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  HttpNetworkTransaction trans(LOW, session.get());
125173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo request;
125193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback callback;
125203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
125213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            trans.Start(&request, callback.callback(), BoundNetLog()));
125223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStreamRequest> fake_request =
125243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      fake_factory->last_stream_request();
125253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_request != NULL);
125263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
125273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_stream != NULL);
125283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(LOW, fake_stream->priority());
125293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  trans.SetPriority(LOWEST);
125313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(LOWEST, fake_stream->priority());
125323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
125333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
12535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The same logic needs to be tested for both ws: and wss: schemes, but this
12536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // test is already parameterised on NextProto, so it uses a loop to verify
12537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // that the different schemes work.
12538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
12539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (size_t i = 0; i < arraysize(test_cases); ++i) {
12540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    HttpNetworkSessionPeer peer(session);
12542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FakeStreamFactory* fake_factory = new FakeStreamFactory();
12543f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
12544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    peer.SetHttpStreamFactoryForWebSocket(
12545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        scoped_ptr<HttpStreamFactory>(fake_factory));
12546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
125471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    HttpNetworkTransaction trans(LOW, session.get());
12548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    trans.SetWebSocketHandshakeStreamCreateHelper(
12549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        &websocket_stream_create_helper);
12550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12551f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    HttpRequestInfo request;
12552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    TestCompletionCallback callback;
12553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    request.method = "GET";
12554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    request.url = GURL(test_cases[i]);
12555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12556f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING,
12557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              trans.Start(&request, callback.callback(), BoundNetLog()));
12558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12559f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::WeakPtr<FakeStreamRequest> fake_request =
12560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        fake_factory->last_stream_request();
12561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(fake_request != NULL);
12562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(&websocket_stream_create_helper,
12563f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              fake_request->websocket_stream_create_helper());
12564f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
12565f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
12566f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
125673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Tests that when a used socket is returned to the SSL socket pool, it's closed
125683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// if the transport socket pool is stalled on the global socket limit.
125693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
125703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_group(
125713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
125723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_pool(
125733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
125743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Set up SSL request.
125763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo ssl_request;
125783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ssl_request.method = "GET";
125793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ssl_request.url = GURL("https://www.google.com/");
125803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockWrite ssl_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 ssl_reads[] = {
125873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
125883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("Content-Length: 11\r\n\r\n"),
125893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("hello world"),
125903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
125913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
125923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
125933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                    ssl_writes, arraysize(ssl_writes));
125943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
125953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
125973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
125983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Set up HTTP request.
126003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo http_request;
126023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  http_request.method = "GET";
126033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  http_request.url = GURL("http://www.google.com/");
126043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockWrite http_writes[] = {
126063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
126073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Host: www.google.com\r\n"
126083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
126093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
126103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockRead http_reads[] = {
126113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
126123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("Content-Length: 7\r\n\r\n"),
126133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("falafel"),
126143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
126153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
126163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
126173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     http_writes, arraysize(http_writes));
126183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&http_data);
126193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
126213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Start the SSL request.
126233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback ssl_callback;
126243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<HttpTransaction> ssl_trans(
126253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
126263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING,
126273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            ssl_trans->Start(&ssl_request, ssl_callback.callback(),
126283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            BoundNetLog()));
126293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Start the HTTP request.  Pool should stall.
126313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback http_callback;
126323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<HttpTransaction> http_trans(
126333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
126343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING,
126353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            http_trans->Start(&http_request, http_callback.callback(),
126363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                              BoundNetLog()));
126371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
126383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Wait for response from SSL request.
126403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, ssl_callback.WaitForResult());
126413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string response_data;
126423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
126433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
126443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // The SSL socket should automatically be closed, so the HTTP request can
126463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // start.
126471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
126481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
126493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // The HTTP request can now complete.
126513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, http_callback.WaitForResult());
126523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
126533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ("falafel", response_data);
126543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
126563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
126573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Tests that when a SSL connection is established but there's no corresponding
126593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// request that needs it, the new socket is closed if the transport socket pool
126603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// is stalled on the global socket limit.
126613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
126623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_group(
126633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
126643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_pool(
126653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
126663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Set up an ssl request.
126683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo ssl_request;
126703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ssl_request.method = "GET";
126713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ssl_request.url = GURL("https://www.foopy.com/");
126723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // No data will be sent on the SSL socket.
126743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StaticSocketDataProvider ssl_data;
126753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
126763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
126783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
126793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Set up HTTP request.
126813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo http_request;
126833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  http_request.method = "GET";
126843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  http_request.url = GURL("http://www.google.com/");
126853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockWrite http_writes[] = {
126873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
126883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Host: www.google.com\r\n"
126893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
126903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
126913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockRead http_reads[] = {
126923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
126933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("Content-Length: 7\r\n\r\n"),
126943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("falafel"),
126953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
126963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
126973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
126983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     http_writes, arraysize(http_writes));
126993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&http_data);
127003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
127013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
127023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
127033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Preconnect an SSL socket.  A preconnect is needed because connect jobs are
127043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // cancelled when a normal transaction is cancelled.
127053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
127063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  net::SSLConfig ssl_config;
127073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session->ssl_config_service()->GetSSLConfig(&ssl_config);
127083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
127093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                         ssl_config, ssl_config);
127101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
127113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
127123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Start the HTTP request.  Pool should stall.
127133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback http_callback;
127143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<HttpTransaction> http_trans(
127153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
127163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING,
127173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            http_trans->Start(&http_request, http_callback.callback(),
127183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                              BoundNetLog()));
127191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
127203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
127213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // The SSL connection will automatically be closed once the connection is
127223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // established, to let the HTTP request start.
127233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, http_callback.WaitForResult());
127243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string response_data;
127253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
127263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ("falafel", response_data);
127273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
127281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
127293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
127303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
127310529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
127320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
127330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
127340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
127350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
127370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
127380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
127390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
127400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
127410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
127430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
127441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
127450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
127460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
127470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
127480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
127490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
127500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
127510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
127520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
127530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
127550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
127560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("hello world"),
127570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
127580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
127590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
127600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
127610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
127620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
127640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
127660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
127670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
127690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
127700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
127720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_TRUE(response != NULL);
127730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response->headers.get() != NULL);
127750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
127760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string response_data;
127780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = ReadTransaction(trans.get(), &response_data);
127790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
127800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("hello world", response_data);
127810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
127820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// This test makes sure the retry logic doesn't trigger when reading an error
127840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// response from a server that rejected a POST with a CONNECTION_RESET.
127850529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest,
127860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       PostReadsErrorResponseAfterResetOnReusedSocket) {
127870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
127880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
127890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("GET / HTTP/1.1\r\n"
127900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
127910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n\r\n"),
127920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
127930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
127940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
127950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
127960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
127970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
127980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
128000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.1 200 Peachy\r\n"
128010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch             "Content-Length: 14\r\n\r\n"),
128020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("first response"),
128030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.1 400 Not OK\r\n"
128040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch             "Content-Length: 15\r\n\r\n"),
128050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("second response"),
128060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
128070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
128080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
128090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
128100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
128110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
128130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request1;
128140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request1.method = "GET";
128150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request1.url = GURL("http://www.foo.com/");
128160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request1.load_flags = 0;
128170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans1(
128191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
128200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
128210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
128220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
128240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
128250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
128270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_TRUE(response1 != NULL);
128280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response1->headers.get() != NULL);
128300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
128310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string response_data1;
128330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = ReadTransaction(trans1.get(), &response_data1);
128340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
128350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("first response", response_data1);
128360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Delete the transaction to release the socket back into the socket pool.
128370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  trans1.reset();
128380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
128400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
128410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
128420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request2;
128440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request2.method = "POST";
128450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request2.url = GURL("http://www.foo.com/");
128460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request2.upload_data_stream = &upload_data_stream;
128470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request2.load_flags = 0;
128480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans2(
128501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
128510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
128520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
128530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
128550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
128560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
128580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_TRUE(response2 != NULL);
128590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response2->headers.get() != NULL);
128610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
128620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string response_data2;
128640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = ReadTransaction(trans2.get(), &response_data2);
128650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
128660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("second response", response_data2);
128670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
128680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128690529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest,
128700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       PostReadsErrorResponseAfterResetPartialBodySent) {
128710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
128720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
128730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
128740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
128760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
128770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
128780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
128790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
128800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
128820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
128831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
128840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
128850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
128860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
128870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
128880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
128890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"
128900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "fo"),
128910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
128920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
128930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
128950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
128960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("hello world"),
128970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
128980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
128990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
129000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
129010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
129020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
129040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
129060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
129070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
129090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
129100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
129120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_TRUE(response != NULL);
129130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response->headers.get() != NULL);
129150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
129160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string response_data;
129180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = ReadTransaction(trans.get(), &response_data);
129190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
129200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("hello world", response_data);
129210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
129220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// This tests the more common case than the previous test, where headers and
129240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// body are not merged into a single request.
129250529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
129260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
129270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
129280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0);
129290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
129310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
129320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
129330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
129340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
129350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
129370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
129381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
129390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
129400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
129410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
129420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
129430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
129440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Transfer-Encoding: chunked\r\n\r\n"),
129450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
129460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
129470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
129490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
129500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("hello world"),
129510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
129520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
129530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
129540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
129550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
129560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
129580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
129600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
129610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Make sure the headers are sent before adding a chunk.  This ensures that
129620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // they can't be merged with the body in a single send.  Not currently
129630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // necessary since a chunked body is never merged with headers, but this makes
129640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // the test more future proof.
129650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::RunLoop().RunUntilIdle();
129660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  upload_data_stream.AppendChunk("last chunk", 10, true);
129680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
129700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
129710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
129730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_TRUE(response != NULL);
129740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response->headers.get() != NULL);
129760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
129770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string response_data;
129790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = ReadTransaction(trans.get(), &response_data);
129800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
129810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("hello world", response_data);
129820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
129830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129840529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
129850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
129860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
129870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
129880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
129900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
129910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
129920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
129930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
129940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
129960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
129971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
129980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
130000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
130010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
130020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
130030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
130040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
130050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
130060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
130080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
130090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
130100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("hello world"),
130110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
130120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
130130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
130140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
130150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
130160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
130180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
130200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
130210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
130230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
130240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
130260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_TRUE(response != NULL);
130270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response->headers.get() != NULL);
130290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
130300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string response_data;
130320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = ReadTransaction(trans.get(), &response_data);
130330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
130340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("hello world", response_data);
130350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
130360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130370529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
130380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
130390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
130400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
130410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
130430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
130440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
130450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
130460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
130470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
130490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
130501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
130510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
130520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
130530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
130540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
130550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
130560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
130570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
130580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
130590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
130610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
130620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("hello world"),
130630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
130640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
130650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
130660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
130670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
130680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
130700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
130720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
130730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
130750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
130760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
130780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response == NULL);
130790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
130800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130810529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest,
130820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       PostIgnoresNonErrorResponseAfterResetAnd100) {
130830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
130840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
130850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
130860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
130880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
130890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
130900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
130910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
130920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
130940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
130951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
130960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
130970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
130980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
130990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
131000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
131010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
131020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
131030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
131040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
131060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
131070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 302 Redirect\r\n"),
131080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("Location: http://somewhere-else.com/\r\n"),
131090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("Content-Length: 0\r\n\r\n"),
131100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
131110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
131120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
131130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
131140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
131150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
131170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
131190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
131200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
131220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
131230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
131250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response == NULL);
131260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
131270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131280529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
131290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
131300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
131310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
131320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
131340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
131350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
131360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
131370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
131380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
131400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
131411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
131420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
131430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
131440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
131450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
131460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
131470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
131480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
131490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
131500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
131520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP 0.9 rocks!"),
131530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
131540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
131550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
131560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
131570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
131580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
131600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
131620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
131630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
131650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
131660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
131680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response == NULL);
131690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
131700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131710529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
131720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
131730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
131740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
131750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
131770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
131780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
131790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
131800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
131810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
131830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
131841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
131850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
131860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
131870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
131880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
131890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
131900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
131910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
131920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
131930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
131950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
131960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
131970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
131980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
131990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
132000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
132010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
132020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
132030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
132040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
132050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
132060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
132070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
132080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
132090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
132100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
132110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response == NULL);
132120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
132130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
132145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
13215