http_network_transaction_unittest.cc revision 116680a4aac90f2aa7413d9095a592090648e557
17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_network_transaction.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <math.h>  // ceil
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdarg.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_writer.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/memory/weak_ptr.h"
1923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/run_loop.h"
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_file_util.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/auth.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/capturing_net_log.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/load_timing_info.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/load_timing_info_test_util.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_log_unittest.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/request_priority.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_completion_callback.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/test_data_directory.h"
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_bytes_element_reader.h"
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/upload_data_stream.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/upload_file_element_reader.h"
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cert/mock_cert_verifier.h"
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/dns/host_cache.h"
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/dns/mock_host_resolver.h"
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/http/http_auth_challenge_tokenizer.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_auth_handler_digest.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_auth_handler_mock.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_auth_handler_ntlm.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_basic_stream.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_network_session.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_network_session_peer.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_server_properties_impl.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_stream.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_stream_factory.h"
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/http/http_transaction_test_util.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_config_service_fixed.h"
513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "net/proxy/proxy_info.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_resolver.h"
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_service.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_factory.h"
55a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)#include "net/socket/client_socket_pool_manager.h"
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/mock_client_socket_pool_manager.h"
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/socket/next_proto.h"
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/socket_test_util.h"
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/ssl_client_socket.h"
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_framer.h"
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_session.h"
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_session_pool.h"
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/spdy/spdy_test_util_common.h"
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_cert_request_info.h"
653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "net/ssl/ssl_config_service.h"
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_config_service_defaults.h"
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_info.h"
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/test/cert_test_util.h"
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/websockets/websocket_handshake_stream_base.h"
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/platform_test.h"
72ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "url/gurl.h"
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::ASCIIToUTF16;
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kBar(ASCIIToUTF16("bar"));
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kBar2(ASCIIToUTF16("bar2"));
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kBar3(ASCIIToUTF16("bar3"));
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kBaz(ASCIIToUTF16("baz"));
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kFirst(ASCIIToUTF16("first"));
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kFoo(ASCIIToUTF16("foo"));
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kFoo2(ASCIIToUTF16("foo2"));
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kFoo3(ASCIIToUTF16("foo3"));
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kFou(ASCIIToUTF16("fou"));
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kSecond(ASCIIToUTF16("second"));
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return session->GetTransportSocketPool(
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return session->GetSSLSocketPool(
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool IsTransportSocketPoolStalled(net::HttpNetworkSession* session) {
1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return session->GetTransportSocketPool(
1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IsStalled();
1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Takes in a Value created from a NetLogHttpResponseParameter, and returns
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a JSONified list of headers as a single string.  Uses single quotes instead
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of double quotes for easier comparison.  Returns false on failure.
1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!params)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  base::ListValue* header_list;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!params->GetList("headers", &header_list))
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string double_quote_headers;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::JSONWriter::Write(header_list, &double_quote_headers);
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::ReplaceChars(double_quote_headers, "\"", "'", headers);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// used.
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.socket_reused);
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.send_start.is_null());
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Set at a higher level.
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start_time.is_null());
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start.is_null());
14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// used.
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             int connect_timing_flags) {
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.socket_reused);
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                   connect_timing_flags);
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.connect_timing.connect_end,
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.send_start);
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Set at a higher level.
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start_time.is_null());
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start.is_null());
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// used.
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.socket_reused);
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_start,
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.proxy_resolve_end);
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_end,
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.send_start);
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Set at a higher level.
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start_time.is_null());
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start.is_null());
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// used.
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    int connect_timing_flags) {
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.socket_reused);
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_start,
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.proxy_resolve_end);
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_end,
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.connect_timing.connect_start);
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   connect_timing_flags);
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.connect_timing.connect_end,
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.send_start);
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Set at a higher level.
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start_time.is_null());
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.request_start.is_null());
20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return SpdySessionDependencies::SpdyCreateSession(session_deps);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class HttpNetworkTransactionTest
2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : public PlatformTest,
2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      public ::testing::WithParamInterface<NextProto> {
227a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) public:
2287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual ~HttpNetworkTransactionTest() {
229a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // Important to restore the per-pool limit first, since the pool limit must
230a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    // always be greater than group limit, and the tests reduce both limits.
231a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    ClientSocketPoolManager::set_max_sockets_per_pool(
232a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
233a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    ClientSocketPoolManager::set_max_sockets_per_group(
234a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
235a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
236a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
2387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  HttpNetworkTransactionTest()
2397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      : spdy_util_(GetParam()),
2407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        session_deps_(GetParam()),
241a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
242a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            HttpNetworkSession::NORMAL_SOCKET_POOL)),
243a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
244a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)            HttpNetworkSession::NORMAL_SOCKET_POOL)) {
245a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct SimpleGetHelperResult {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string status_line;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string response_data;
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int64 totalReceivedBytes;
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LoadTimingInfo load_timing_info;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Empty the current queue.
26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PlatformTest::TearDown();
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
26790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // This is the expected return from a current server advertising SPDY.
271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string GetAlternateProtocolHttpHeader() {
272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return
273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        std::string("Alternate-Protocol: 443:") +
274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        "\r\n\r\n";
276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Either |write_failure| specifies a write failure or |read_failure|
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // specifies a read failure when using a reused socket.  In either case, the
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // failure should cause the network transaction to resend the request, and the
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other argument should be NULL.
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const MockRead* read_failure);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Either |write_failure| specifies a write failure or |read_failure|
28623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // specifies a read failure when using a reused socket.  In either case, the
28723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // failure should cause the network transaction to resend the request, and the
28823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // other argument should be NULL.
28923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
290effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                        const MockRead* read_failure,
291effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                        bool use_spdy);
29223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               size_t data_count) {
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleGetHelperResult out;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/");
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CapturingBoundNetLog log;
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.net_log = log.bound().net_log();
3048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
3068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < data_count; ++i) {
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.socket_factory->AddSocketDataProvider(data[i]);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_TRUE(log.bound().IsLogging());
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), log.bound());
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.rv = callback.WaitForResult();
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Even in the failure cases that use this function, connections are always
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // successfully established before the error.
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (out.rv != OK)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return out;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Can't use ASSERT_* inside helper functions like this, so
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // return an error.
331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (response == NULL || response->headers.get() == NULL) {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      out.rv = ERR_UNEXPECTED;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return out;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    out.status_line = response->headers->GetStatusLine();
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ("127.0.0.1", response->socket_address.host());
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(80, response->socket_address.port());
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ReadTransaction(trans.get(), &out.response_data);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::CapturingNetLog::CapturedEntryList entries;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    log.GetEntries(&entries);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    size_t pos = ExpectLogContainsSomewhere(
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NetLog::PHASE_NONE);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExpectLogContainsSomewhere(
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        entries, pos,
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NetLog::PHASE_NONE);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string line;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("GET / HTTP/1.1\r\n", line);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    HttpRequestHeaders request_headers;
358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::string value;
360eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_TRUE(request_headers.GetHeader("Host", &value));
361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_EQ("www.google.com", value);
362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_EQ("keep-alive", value);
364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    std::string response_headers;
366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              response_headers);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    out.totalReceivedBytes = trans->GetTotalReceivedBytes();
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return out;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        size_t reads_count) {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider* data[] = { &reads };
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SimpleGetHelperForData(data, 1);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int64 size = 0;
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    for (size_t i = 0; i < reads_count; ++i)
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      size += data_reads[i].data_len;
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return size;
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             int expected_status);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ConnectStatusHelper(const MockRead& status);
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void BypassHostCacheOnRefreshHelper(int load_flags);
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void CheckErrorIsPassedBack(int error, IoMode mode);
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
397a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SpdyTestUtil spdy_util_;
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SpdySessionDependencies session_deps_;
399a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
400a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Original socket limits.  Some tests set these.  Safest to always restore
401a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // them once each test has been run.
402a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  int old_max_group_sockets_;
403a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  int old_max_pool_sockets_;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(
4077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    NextProto,
4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    HttpNetworkTransactionTest,
4094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    testing::Values(kProtoDeprecatedSPDY2,
410a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                    kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class BeforeNetworkStartHandler {
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit BeforeNetworkStartHandler(bool defer)
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : defer_on_before_network_start_(defer),
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        observed_before_network_start_(false) {}
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void OnBeforeNetworkStart(bool* defer) {
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *defer = defer_on_before_network_start_;
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    observed_before_network_start_ = true;
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool observed_before_network_start() const {
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return observed_before_network_start_;
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const bool defer_on_before_network_start_;
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool observed_before_network_start_;
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
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 */)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template <>
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostResolver* host_resolver,
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CertVerifier* cert_verifier)
574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : SSLClientSocketPool(0,
575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          0,
576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          host_resolver,
578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          cert_verifier,
579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
581a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          NULL,
582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          std::string(),
583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL,
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          NULL) {}
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//-----------------------------------------------------------------------------
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper functions for validating that AuthChallengeInfo's are correctly
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// configured for common cases.
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_challenge)
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(auth_challenge->is_proxy);
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("MyRealm1", auth_challenge->realm);
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", auth_challenge->scheme);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_challenge)
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(auth_challenge->is_proxy);
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("MyRealm1", auth_challenge->realm);
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", auth_challenge->scheme);
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_challenge)
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(auth_challenge->is_proxy);
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("digestive", auth_challenge->realm);
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("digest", auth_challenge->scheme);
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!auth_challenge)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(auth_challenge->is_proxy);
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(std::string(), auth_challenge->realm);
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("ntlm", auth_challenge->scheme);
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Basic) {
6378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
6398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SimpleGET) {
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", out.response_data);
6535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
6545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Response with no status line.
6587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", out.response_data);
6685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Allow up to 4 bytes of junk to precede status line.
6737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("DATA", out.response_data);
6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Allow up to 4 bytes of junk to precede status line.
6887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("DATA", out.response_data);
6985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
6995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Beyond 4 bytes of slop and it should fail to find a status line.
7037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
7135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
7145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
7187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\n"),
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\n"),
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Q"),
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("J"),
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("DATA", out.response_data);
7325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
7335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Close the connection before enough bytes to have a status line.
7377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTT"),
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTT", out.response_data);
7475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
7485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, out.totalReceivedBytes);
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Simulate a 204 response, lacking a Content-Length header, sent over a
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// persistent connection.  The response should still terminate since a 204
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cannot have a response body.
7547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StopsReading204) {
7555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  char junk[] = "junk";
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
7585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead(junk),  // Should not be read!!
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", out.response_data);
7665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
7675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 response_size = reads_size - strlen(junk);
7685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(response_size, out.totalReceivedBytes);
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A simple request using chunked encoding with some extra data after.
7727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
7735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string final_chunk = "0\r\n\r\n";
7745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string extra_data = "HTTP/1.1 200 OK\r\n";
7755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string last_read = final_chunk + extra_data;
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("5\r\nHello\r\n"),
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("1\r\n"),
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(" \r\n"),
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("5\r\nworld\r\n"),
7825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead(last_read.data()),
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello world", out.response_data);
7905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
7915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 response_size = reads_size - extra_data.size();
7925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(response_size, out.totalReceivedBytes);
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Next tests deal with http://crbug.com/56344.
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       MultipleContentLengthHeadersNoTransferEncoding) {
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n"),
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       DuplicateContentLengthHeadersNoTransferEncoding) {
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n"),
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello", out.response_data);
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ComplexContentLengthHeadersNoTransferEncoding) {
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // More than 2 dupes.
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads[] = {
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 200 OK\r\n"),
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n"),
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n"),
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n\r\n"),
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Hello"),
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                arraysize(data_reads));
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, out.rv);
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("Hello", out.response_data);
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HTTP/1.0
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads[] = {
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n"),
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n"),
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n\r\n"),
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Hello"),
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                arraysize(data_reads));
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, out.rv);
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("Hello", out.response_data);
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2 dupes and one mismatched.
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads[] = {
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 200 OK\r\n"),
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10\r\n"),
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10\r\n"),
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 5\r\n\r\n"),
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                arraysize(data_reads));
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       MultipleContentLengthHeadersTransferEncoding) {
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 666\r\n"),
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 1337\r\n"),
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Transfer-Encoding: chunked\r\n\r\n"),
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("5\r\nHello\r\n"),
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("1\r\n"),
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(" \r\n"),
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("5\r\nworld\r\n"),
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello world", out.response_data);
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Next tests deal with http://crbug.com/98895.
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that a single Content-Disposition header results in no error.
8947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello", out.response_data);
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two identical Content-Disposition headers result in no error.
9097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       TwoIdenticalContentDispositionHeaders) {
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, out.rv);
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Hello", out.response_data);
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two distinct Content-Disposition headers result in an error.
9267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two identical Location headers result in no error.
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Also tests Location header behavior.
9417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Redirect\r\n"),
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://good.com/\r\n"),
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://good.com/\r\n"),
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://redirect.com/");
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
970868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsRedirect(&url));
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://good.com/", url);
975f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(response->proxy_server.IsEmpty());
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two distinct Location headers result in an error.
9797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Redirect\r\n"),
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://good.com/\r\n"),
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://evil.com/\r\n"),
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Do a request using the HEAD method. Verify that we don't try to read the
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// message body (since HEAD has none).
9947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Head) {
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "HEAD";
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
1003116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  BeforeProxyHeadersSentHandler proxy_headers_handler;
1004116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  trans->SetBeforeProxyHeadersSentCallback(
1005116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1006116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::Unretained(&proxy_headers_handler)));
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("HEAD / HTTP/1.1\r\n"
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 404 Not Found\r\n"),
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Server: Blah\r\n"),
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 1234\r\n\r\n"),
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No response body because the test stops reading here.
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
1025c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the headers got parsed.
1039868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1234, response->headers->GetContentLength());
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
1042f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(response->proxy_server.IsEmpty());
1043116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string server_header;
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* iter = NULL;
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_server_header = response->headers->EnumerateHeader(
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &iter, "Server", &server_header);
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(has_server_header);
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Blah", server_header);
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reading should give EOF right away, since there is no message body
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (despite non-zero content-length).
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", response_data);
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
1061c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("world"),
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1071c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kExpectedResponseData[] = {
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "hello", "world"
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; ++i) {
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/");
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
1084868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1097868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response->headers.get() != NULL);
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1099f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_TRUE(response->proxy_server.IsEmpty());
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string response_data;
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ReadTransaction(trans.get(), &response_data);
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kExpectedResponseData[i], response_data);
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Ignores100) {
11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(new UploadBytesElementReader("foo", 3));
111168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.upload_data_stream = &upload_data_stream;
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
11218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test is almost the same as Ignores100 above, but the response contains
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HTTP/1.1 and the two status headers are read in one read.
11557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
11638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "HTTP/1.1 200 OK\r\n\r\n"),
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
12028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0),
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", response_data);
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
12338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0),
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockWrite* write_failure,
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockRead* read_failure) {
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
1260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
1261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Written data for successfully sending both requests.
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data1_writes[] = {
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.foo.com\r\n"
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.foo.com\r\n"
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read results for the first request.
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data1_reads[] = {
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (write_failure) {
128123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ASSERT_FALSE(read_failure);
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data1_writes[1] = *write_failure;
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(read_failure);
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data1_reads[2] = *read_failure;
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data1_writes, arraysize(data1_writes));
1290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data2_reads[] = {
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("world"),
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kExpectedResponseData[] = {
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "hello", "world"
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 first_socket_log_id = NetLog::Source::kInvalidId;
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; ++i) {
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
1309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LoadTimingInfo load_timing_info;
13182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
13192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
13202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i == 0) {
13212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      first_socket_log_id = load_timing_info.socket_log_id;
13222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
13232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // The second request should be using a new socket.
13242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
13252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
13262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response->headers.get() != NULL);
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string response_data;
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ReadTransaction(trans.get(), &response_data);
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kExpectedResponseData[i], response_data);
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
134023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
134123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    const MockWrite* write_failure,
1342effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    const MockRead* read_failure,
1343effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    bool use_spdy) {
134423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  HttpRequestInfo request;
134523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  request.method = "GET";
1346effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  request.url = GURL("https://www.foo.com/");
134723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  request.load_flags = 0;
134823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
134923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  CapturingNetLog net_log;
135023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  session_deps_.net_log = &net_log;
135123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
135223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1353effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  SSLSocketDataProvider ssl1(ASYNC, OK);
1354effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  SSLSocketDataProvider ssl2(ASYNC, OK);
1355effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (use_spdy) {
1356effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ssl1.SetNextProto(GetParam());
1357effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ssl2.SetNextProto(GetParam());
1358effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
1359effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1360effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
1361effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1362effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // SPDY versions of the request and response.
1363effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1364effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1365effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<SpdyFrame> spdy_response(
1366effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1367effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  scoped_ptr<SpdyFrame> spdy_data(
1368effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
1369effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1370effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // HTTP/1.1 versions of the request and response.
1371effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1372effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      "Host: www.foo.com\r\n"
1373effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      "Connection: keep-alive\r\n\r\n";
1374effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1375effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  const char kHttpData[] = "hello";
1376effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1377effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<MockRead> data1_reads;
1378effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<MockWrite> data1_writes;
137923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (write_failure) {
138023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ASSERT_FALSE(read_failure);
1381effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data1_writes.push_back(*write_failure);
1382effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data1_reads.push_back(MockRead(ASYNC, OK));
138323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  } else {
138423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    ASSERT_TRUE(read_failure);
1385effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    if (use_spdy) {
1386effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      data1_writes.push_back(CreateMockWrite(*spdy_request));
1387effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    } else {
1388effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      data1_writes.push_back(MockWrite(kHttpRequest));
1389effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    }
1390effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data1_reads.push_back(*read_failure);
139123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
139223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1393effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1394effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                 &data1_writes[0], data1_writes.size());
139523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
139623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1397effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<MockRead> data2_reads;
1398effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  std::vector<MockWrite> data2_writes;
1399effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1400effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (use_spdy) {
1401effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1402effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1403effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1404effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1405effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_reads.push_back(MockRead(ASYNC, OK, 3));
1406effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  } else {
1407effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_writes.push_back(
1408effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1409effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1410effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_reads.push_back(
1411effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1412effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1413effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    data2_reads.push_back(MockRead(ASYNC, OK, 3));
1414effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
1415effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  OrderedSocketData data2(&data2_reads[0], data2_reads.size(),
1416effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                          &data2_writes[0], data2_writes.size());
141723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
141823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
141923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Preconnect a socket.
142023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  net::SSLConfig ssl_config;
142123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  session->ssl_config_service()->GetSSLConfig(&ssl_config);
1422cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session->GetNextProtos(&ssl_config.next_protos);
142323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  session->http_stream_factory()->PreconnectStreams(
142423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
142523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Wait for the preconnect to complete.
142623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // TODO(davidben): Some way to wait for an idle socket count might be handy.
142723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  base::RunLoop().RunUntilIdle();
1428effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
142923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
143023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // Make the request.
143123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  TestCompletionCallback callback;
143223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
143323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
143423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
143523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
143623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
143723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
143823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
143923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  rv = callback.WaitForResult();
144023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_EQ(OK, rv);
144123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
144223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  LoadTimingInfo load_timing_info;
144323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1444effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  TestLoadTimingNotReused(
1445effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      load_timing_info,
1446effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
144723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
144823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
144923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
145023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
145123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
145223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
145323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
145423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  std::string response_data;
145523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
145623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_EQ(OK, rv);
1457effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  EXPECT_EQ(kHttpData, response_data);
145823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
145923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
14607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       KeepAliveConnectionNotConnectedOnWrite) {
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeepAliveConnectionResendRequestTest(&write_failure, NULL);
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeepAliveConnectionResendRequestTest(NULL, &read_failure);
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead read_failure(SYNCHRONOUS, OK);  // EOF
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeepAliveConnectionResendRequestTest(NULL, &read_failure);
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
147646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Make sure that on a 408 response (Request Timeout), the request is retried,
147746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// if the socket was a reused keep alive socket.
147846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
147946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  MockRead read_failure(SYNCHRONOUS,
148046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "HTTP/1.1 408 Request Timeout\r\n"
148146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "Connection: Keep-Alive\r\n"
148246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "Content-Length: 6\r\n\r\n"
148346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "Pickle");
148446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  KeepAliveConnectionResendRequestTest(NULL, &read_failure);
148546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
148646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
148723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
148823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)       PreconnectErrorNotConnectedOnWrite) {
148923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1490effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(&write_failure, NULL, false);
149123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
149223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
149323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
149423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1495effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(NULL, &read_failure, false);
149623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
149723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
149823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
149923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  MockRead read_failure(SYNCHRONOUS, OK);  // EOF
1500effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1501effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
1502effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1503effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1504effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MockRead read_failure(ASYNC, OK);  // EOF
1505effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1506effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
1507effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
150846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Make sure that on a 408 response (Request Timeout), the request is retried,
150946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// if the socket was a preconnected (UNUSED_IDLE) socket.
151046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
151146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  MockRead read_failure(SYNCHRONOUS,
151246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "HTTP/1.1 408 Request Timeout\r\n"
151346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "Connection: Keep-Alive\r\n"
151446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "Content-Length: 6\r\n\r\n"
151546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)                        "Pickle");
151646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  KeepAliveConnectionResendRequestTest(NULL, &read_failure);
151746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  PreconnectErrorResendRequestTest(NULL, &read_failure, false);
151846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
151946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
1520effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(HttpNetworkTransactionTest,
1521effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch       SpdyPreconnectErrorNotConnectedOnWrite) {
1522effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1523effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1524effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
1525effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1526effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1527effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1528effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1529effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
1530effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1531effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1532effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MockRead read_failure(SYNCHRONOUS, OK);  // EOF
1533effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1534effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
1535effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1536effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochTEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1537effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  MockRead read_failure(ASYNC, OK);  // EOF
1538effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PreconnectErrorResendRequestTest(NULL, &read_failure, true);
153923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
154023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
15417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
15498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_CONNECTION_RESET),
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response == NULL);
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// What do various browsers do when the server closes a non-keepalive
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection without sending any response header or body?
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// IE7: error page
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Safari 3.1.2 (Windows): error page
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Firefox 3.0.1: blank page
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Opera 9.52: after five attempts, blank page
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Us: error page (EMPTY_RESPONSE)
15817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),  // EOF
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SimpleGetHelperResult out = SimpleGetHelper(data_reads,
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              arraysize(data_reads));
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test that network access can be deferred and resumed.
15945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
15955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  HttpRequestInfo request;
15965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.method = "GET";
15975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
15985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.load_flags = 0;
15995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
16025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Defer on OnBeforeNetworkStart.
16055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BeforeNetworkStartHandler net_start_handler(true);  // defer
16065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  trans->SetBeforeNetworkStartCallback(
16075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
16085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(&net_start_handler)));
16095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MockRead data_reads[] = {
16115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
16125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
16135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead("hello"),
16145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockRead(SYNCHRONOUS, 0),
16155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
16165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
16175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
16185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestCompletionCallback callback;
16205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
16225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
16235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
16245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Should have deferred for network start.
16265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(net_start_handler.observed_before_network_start());
16275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
16285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(trans->GetResponseInfo() == NULL);
16295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  trans->ResumeNetworkStart();
16315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rv = callback.WaitForResult();
16325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(OK, rv);
16335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(trans->GetResponseInfo() != NULL);
16345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
16365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
16375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
16385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    rv = callback.WaitForResult();
16395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(5, rv);
16405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  trans.reset();
16415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
16425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Test that network use can be deferred and canceled.
16445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
16455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  HttpRequestInfo request;
16465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.method = "GET";
16475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
16485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  request.load_flags = 0;
16495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
16525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Defer on OnBeforeNetworkStart.
16555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  BeforeNetworkStartHandler net_start_handler(true);  // defer
16565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  trans->SetBeforeNetworkStartCallback(
16575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
16585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 base::Unretained(&net_start_handler)));
16595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestCompletionCallback callback;
16615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
16635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
16645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
16655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Should have deferred for network start.
16675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(net_start_handler.observed_before_network_start());
16685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
16695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(trans->GetResponseInfo() == NULL);
16705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
16715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// tests. There was a bug causing HttpNetworkTransaction to hang in the
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// destructor in such situations.
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See http://crbug.com/154712 and http://crbug.com/156609.
16767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1684868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: keep-alive\r\n"),
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, 0),
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1705868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, rv);
1709868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
171390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1725868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: keep-alive\r\n"),
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, 0),
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1745868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
175190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we correctly reuse a keep-alive connection after not explicitly
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reading the body.
17577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
1764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
1765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that because all these reads happen in the same
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // StaticSocketDataProvider, it shows that the same socket is being reused for
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // all transactions.
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data1_reads[] = {
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Found\r\n"
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 0\r\n\r\n"),
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Found\r\n"
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 5\r\n\r\n"
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "hello"),
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 301 Moved Permanently\r\n"
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 0\r\n\r\n"),
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 301 Moved Permanently\r\n"
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 5\r\n\r\n"
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "hello"),
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
1788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data2_reads[] = {
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
1794c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kNumUnreadBodies = arraysize(data1_reads) - 2;
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_lines[kNumUnreadBodies];
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 first_socket_log_id = NetLog::Source::kInvalidId;
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
1804868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LoadTimingInfo load_timing_info;
18132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
18142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (i == 0) {
18152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
18162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      first_socket_log_id = load_timing_info.socket_log_id;
18172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
18182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      TestLoadTimingReused(load_timing_info);
18192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
18202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
18212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    ASSERT_TRUE(response->headers.get() != NULL);
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response_lines[i] = response->headers->GetStatusLine();
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We intentionally don't read the response bodies.
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kStatusLines[] = {
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 204 No Content",
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 205 Reset Content",
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 304 Not Modified",
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 302 Found",
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 302 Found",
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 301 Moved Permanently",
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "HTTP/1.1 301 Moved Permanently",
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 forgot_to_update_kStatusLines);
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kNumUnreadBodies; ++i)
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kStatusLines[i], response_lines[i]);
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
18482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
1849868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
1856868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello", response_data);
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth.
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (basic auth is the easiest to mock, because it has no randomness).
18667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuth) {
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog log;
1873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &log;
18748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
18768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Give a couple authenticate options (only the middle one is actually
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // supported).
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Large content-length -- won't matter, as connection will be reset.
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10000\r\n\r\n"),
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), this is the request we should
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be issuing -- the final header line contains the credentials.
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
1918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
1919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
19302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
19312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
19322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
19345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
19355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
19502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
19512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
19522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The load timing after restart should have a new socket ID, and times after
19532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // those of the first load timing.
19542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info1.receive_headers_end,
19552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info2.connect_timing.connect_start);
19562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
19572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
19595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
19605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
19758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Large content-length -- won't matter, as connection will be reset.
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10000\r\n\r\n"),
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
1994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, rv);
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
20045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
20055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection.
20137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog log;
2020c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &log;
2021c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 14\r\n\r\n"),
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Unauthorized\r\n"),
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly, the server responds with the actual content.
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Hello"),
20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If there is a regression where we disconnect a Keep-Alive
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection during an auth roundtrip, we'll end up reading this.
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NULL, 0);
2060c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
2061c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2066868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
20742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
20752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
20762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
20912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
20922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info2);
20932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The load timing after restart should have the same socket ID, and times
20942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // those of the first load timing.
20952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info1.receive_headers_end,
20962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info2.send_start);
20972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
20982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
21035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
21045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string response_data;
21055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
21065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(OK, rv);
21075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
21085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection and with no response body to drain.
21137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly, the server responds with the actual content.
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An incorrect reconnect would cause this to be read.
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NULL, 0);
2155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
2156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection and with a large response body to drain.
21897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Respond with 5 kb of response body.
22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string large_body_string("Unauthorized");
22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  large_body_string.append(5 * 1024, ' ');
22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  large_body_string.append("\r\n");
22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 5134 = 12 + 5 * 1024 + 2
22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5134\r\n\r\n"),
22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly, the server responds with the actual content.
22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An incorrect reconnect would cause this to be read.
22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 NULL, 0);
2239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
2240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// connection, but the server gets impatient and closes the connection.
22737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This simulates the seemingly successful write to a closed connection
22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // if the bug is not fixed.
22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 14\r\n\r\n"),
22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Tell MockTCPClientSocket to simulate the server closing the connection.
22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Unauthorized\r\n"),
23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),  // The server closes the connection.
23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), this is the request we should
23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be issuing -- the final header line contains the credentials.
23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello"),
23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
2325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
2326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2331868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a connection
23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that requires a restart when setting up an SSL tunnel.
23597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the no authentication data flag is set.
23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
2367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
23682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No credentials.
23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Connection: close\r\n\r\n"),
23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 5\r\n\r\n"),
24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, "hello"),
24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2416868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2435868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
24375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
24412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CONNECT requests and responses are handled at the connect job level, so
24422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the transaction does not yet have a connection.
24432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
24442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
24662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
24672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
24682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, over a keep-alive
24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// proxy connection, when setting up an SSL tunnel.
24757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that proxy authentication is attempted even
24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the no authentication data flag is set.
24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
2484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2490868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No credentials.
25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("0123456789"),
25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Wrong credentials (wrong password).
25165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
25175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
25185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
25195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No response body because the test stops reading here.
25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
25215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
25225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
25245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
25345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
25355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
25365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
25375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
25385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
25395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
25405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
25415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
25425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
25435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
25455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2546868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
25475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
25485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
25495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, response->headers->GetContentLength());
25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
25515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
25525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wrong password (should be "bar").
25565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
25575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBaz), callback2.callback());
25585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
25595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
25615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
25625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
25645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
2565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
25665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
25675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
25685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, response->headers->GetContentLength());
25695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
25705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
25715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Flush the idle socket before the NetLog and HttpNetworkTransaction go
25735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // out of scope.
25745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
25755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that we don't read the response body when we fail to establish a tunnel,
25785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// even if the user cancels the proxy's auth attempt.
25797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
25805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
25815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
25825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
25835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
25845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
2586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
25875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
25895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
25925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
25945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
25955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
25965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
25975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
25985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 407.
26015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
26025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
26035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
26045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
26065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
26075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
2610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
26155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
26165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
26195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
26225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
26245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
26255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(10, response->headers->GetContentLength());
26265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
26275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
26295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
26305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
26315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
26335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
26345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
26375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
26387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
26395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
26405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
26415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
26425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We are using a DIRECT connection (i.e. no proxy) for this session.
26458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
26465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
26478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
26505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Large content-length -- won't matter, as connection will be reset.
26595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10000\r\n\r\n"),
26605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
26615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
26645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
26665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
26685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
26705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
26715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
26735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
26745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// through a non-authenticating proxy. The request should fail with
26785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ERR_UNEXPECTED_PROXY_AUTH.
26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that it is impossible to detect if an HTTP server returns a 407 through
26805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a non-authenticating proxy - there is nothing to indicate whether the
26815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// response came from the proxy or the server, so it is treated as if the proxy
26825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// issued the challenge.
26837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
26845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       HttpsServerRequestsProxyAuthThroughProxy) {
26855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
26875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
26935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
26955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
26965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
26985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
27025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
27035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
27045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Unauthorized\r\n"),
27095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
27105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\r\n"),
27115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
27125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
27175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
27195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2723868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
27245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
27275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
27315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
27325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
27335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
27345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
27365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
27375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
27385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
27395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test the load timing for HTTPS requests with an HTTP proxy.
27427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
27432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
27442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
27452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("https://www.google.com/1");
27462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
27482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
27492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("https://www.google.com/2");
27502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against proxy server "myproxy:70".
2752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
27532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixed("PROXY myproxy:70"));
27542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
2755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
27572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
27592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite data_writes1[] = {
27602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
27612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
27622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
27632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET /1 HTTP/1.1\r\n"
27652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
27662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
27672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET /2 HTTP/1.1\r\n"
27692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
27702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
27712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
27722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
27742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // connection.
27752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead data_reads1[] = {
27762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
27772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
27792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Length: 1\r\n\r\n"),
27802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, "1"),
27812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
27832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Length: 2\r\n\r\n"),
27842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, "22"),
27852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
27862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
27882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2789c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
27902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
27922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback1;
27942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans1(
2795868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
27962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
27972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans1->Start(&request1, callback1.callback(), log.bound());
27982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
27992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback1.WaitForResult();
28012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
28022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
28042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response1 != NULL);
2805868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response1->headers.get() != NULL);
28062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, response1->headers->GetContentLength());
28072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
28092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
28102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
28112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans1.reset();
28132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback2;
28152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
2816868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
28172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback2.callback(), log.bound());
28192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
28202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback2.WaitForResult();
28222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
28232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
28252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response2 != NULL);
2826868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response2->headers.get() != NULL);
28272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, response2->headers->GetContentLength());
28282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
28302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
28312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info2);
28322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
28342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans2.reset();
28362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  session->CloseAllConnections();
28372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
28382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
28407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
28412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
28422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
28432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("https://www.google.com/1");
28442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
28462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
28472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("https://www.google.com/2");
28482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against proxy server "myproxy:70".
2850c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
28512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
28522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
2853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2854c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
28552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
28572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite data_writes1[] = {
28582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
28592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
28602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
28612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET /1 HTTP/1.1\r\n"
28632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
28642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
28652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET /2 HTTP/1.1\r\n"
28672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
28682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
28692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
28702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
28722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // connection.
28732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead data_reads1[] = {
28742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
28752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
28772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Length: 1\r\n\r\n"),
28782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, "1"),
28792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
28812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Length: 2\r\n\r\n"),
28822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, "22"),
28832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
28842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
28862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
28882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
28902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback1;
28922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans1(
2893868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
28942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans1->Start(&request1, callback1.callback(), log.bound());
28962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
28972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback1.WaitForResult();
28992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
29002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
29022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response1 != NULL);
2903868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response1->headers.get() != NULL);
29042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, response1->headers->GetContentLength());
29052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
29072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
29082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info1,
29092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
29102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans1.reset();
29122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback2;
29142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
2915868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
29162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback2.callback(), log.bound());
29182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
29192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback2.WaitForResult();
29212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
29222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
29242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response2 != NULL);
2925868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response2->headers.get() != NULL);
29262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, response2->headers->GetContentLength());
29272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
29292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
29302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReusedWithPac(load_timing_info2);
29312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
29332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans2.reset();
29352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  session->CloseAllConnections();
29362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
29372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a simple get through an HTTPS Proxy.
29397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
29405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
29415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
29425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
29435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
2945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
29465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
29475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
2948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
2949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
29505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should use full url
29525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
29535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
29545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
29555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
29565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
29575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
29595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
29605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
29615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
29625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
29635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
29645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
29665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
2967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
29685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
2969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
29705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
29725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
2974868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
29755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
29775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
29785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
29805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
29815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
29832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
29842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
29852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
29862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
29885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
29895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
29915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
29925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
29935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
29945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
29965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
29975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
29985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY get through an HTTPS Proxy.
30007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
30015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
30025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
30035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
30045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
30055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
3007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
30085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
30095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3010c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3011c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
30125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetch http://www.google.com/ via SPDY
301490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
301590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
30165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
30175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
30197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
30205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
30215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
30225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data),
30235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
30245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
30255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
30275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
30285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
30295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3030c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
30315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
30337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3034c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
30355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
30375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3039868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
30405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
30425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
30435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
30455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
30465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
30482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
30492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
30502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
30512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
30535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
3054868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
30555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
30565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
30585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
30595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUploadData, response_data);
30605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
30615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// Verifies that a session which races and wins against the owning transaction
30636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// (completing prior to host resolution), doesn't fail the transaction.
30646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// Regression test for crbug.com/334413.
30656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
30666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  HttpRequestInfo request;
30676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  request.method = "GET";
30686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
30696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  request.load_flags = 0;
30706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Configure SPDY proxy server "proxy:70".
30726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.proxy_service.reset(
30736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      ProxyService::CreateFixed("https://proxy:70"));
30746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  CapturingBoundNetLog log;
30756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
30766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
30776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Fetch http://www.google.com/ through the SPDY proxy.
30796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_ptr<SpdyFrame> req(
30806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
30816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  MockWrite spdy_writes[] = {CreateMockWrite(*req)};
30826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
30846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
30856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  MockRead spdy_reads[] = {
30866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      CreateMockRead(*resp), CreateMockRead(*data), MockRead(ASYNC, 0, 0),
30876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  };
30886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  DelayedSocketData spdy_data(
30906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      1,  // wait for one write to finish before reading.
30916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      spdy_reads,
30926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      arraysize(spdy_reads),
30936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      spdy_writes,
30946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      arraysize(spdy_writes));
30956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
30966d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
30976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
30986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ssl.SetNextProto(GetParam());
30996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
31006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  TestCompletionCallback callback1;
31026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
31046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
31056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Stall the hostname resolution begun by the transaction.
31076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.host_resolver->set_synchronous_mode(false);
31086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.host_resolver->set_ondemand_mode(true);
31096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
31116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
31126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Race a session to the proxy, which completes first.
31146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.host_resolver->set_ondemand_mode(false);
31156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  SpdySessionKey key(
31166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
31176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  base::WeakPtr<SpdySession> spdy_session =
31186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      CreateSecureSpdySession(session, key, log.bound());
31196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Unstall the resolution begun by the transaction.
31216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.host_resolver->set_ondemand_mode(true);
31226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  session_deps_.host_resolver->ResolveAllPending();
31236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_FALSE(callback1.have_result());
31256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  rv = callback1.WaitForResult();
31266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_EQ(OK, rv);
31276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
31296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
31306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
31316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
31326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  std::string response_data;
31346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
31356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EXPECT_EQ(kUploadData, response_data);
31366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
31376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
31385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY get through an HTTPS Proxy.
31397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
31405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
31415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
31425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
31435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
31445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
3146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
31475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://myproxy:70"));
31485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
31515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first request will be a bare GET, the second request will be a
31535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GET with a Proxy-Authorization header.
31545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> req_get(
315590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
31565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kExtraAuthorizationHeaders[] = {
315790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "proxy-authorization", "Basic Zm9vOmJhcg=="
31585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
31595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> req_get_authorization(
316090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
316190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  arraysize(kExtraAuthorizationHeaders) / 2,
316290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  false,
316390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  3,
316490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  LOWEST,
316590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                  false));
31665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
31675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req_get, 1),
31685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req_get_authorization, 4),
31695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
31705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first response is a 407 proxy authentication challenge, and the second
31725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // response will be a 200 response since the second request includes a valid
31735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Authorization header.
31745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kExtraAuthenticationHeaders[] = {
317590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    "proxy-authenticate", "Basic realm=\"MyRealm1\""
31765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
31775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp_authentication(
31787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdySynReplyError(
31795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "407 Proxy Authentication Required",
31805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
31815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          1));
31825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> body_authentication(
31837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
31847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp_data(
31857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
31867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
31875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
31885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp_authentication, 2),
31895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body_authentication, 3),
31905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp_data, 5),
31915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body_data, 6),
31925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 7),
31935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
31945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data(
31965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
31975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
31995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
32017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
32035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
32055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
32085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
32105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
32115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
32135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
32145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* const response = trans->GetResponseInfo();
32165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
3218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
32195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
32205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
32215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
32225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
32245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
32265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
32275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
32285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
32305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
32315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
32335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response_restart != NULL);
3235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response_restart->headers.get() != NULL);
32365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response_restart->headers->response_code());
32375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
32385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
32395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
32405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
32427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
32435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
32445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
32455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
32465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
32475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
3249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
32505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
32515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
32545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
32575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY
32593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
32603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                LOWEST));
32615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetch https://www.google.com/ via HTTP
32625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char get[] = "GET / HTTP/1.1\r\n"
32645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Host: www.google.com\r\n"
32655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Connection: keep-alive\r\n\r\n";
32665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get(
32677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
32687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp(
32697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
32705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char resp[] = "HTTP/1.1 200 OK\r\n"
32715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 10\r\n\r\n";
32725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp(
32737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
32745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body(
32757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
32765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> window_update(
327790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
32785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
32805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*connect, 1),
32815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*wrapped_get, 3),
328290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      CreateMockWrite(*window_update, 5),
32835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
32845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
32865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_resp, 2, ASYNC),
32875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_get_resp, 4, ASYNC),
32885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body, 6, ASYNC),
32895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body, 7, ASYNC),
32905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 8),
32915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
32925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
32945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
32955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
32975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
32997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
33015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
33025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl2.was_npn_negotiated = false;
33035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl2.protocol_negotiated = kProtoUnknown;
3304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
33055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
33075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
33095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
33105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
33125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
33135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
33152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
33162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
33172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
33185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
33195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
3320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
33215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
33225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
33245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
33255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("1234567890", response_data);
33265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
33275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
33297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
33305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
33315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
33325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
33335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
33345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
3336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
33375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
33385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
33415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
33445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY
33463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
33473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                LOWEST));
33485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetch https://www.google.com/ via SPDY
33495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kMyUrl = "https://www.google.com/";
335090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> get(
335190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
33527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get(
33537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(get, 1));
33547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp(
33557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
33567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> get_resp(
33577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
33585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp(
33597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
33607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
33617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body(
33627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(body, 1));
33635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> window_update_get_resp(
336490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
33655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> window_update_body(
336690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
33675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
33695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*connect, 1),
33705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*wrapped_get, 3),
33715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*window_update_get_resp, 5),
33725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*window_update_body, 7),
33735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
33745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
33765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_resp, 2, ASYNC),
33775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_get_resp, 4, ASYNC),
33785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body, 6, ASYNC),
33795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 8),
33805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
33815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
33835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
33845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
33865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
33887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
33905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
33917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
33927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.protocol_negotiated = GetParam();
3393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
33945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
33965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
33975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
33985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
33995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
34015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
34025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
34042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
34052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
34062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
34085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
3409868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
34105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
34115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
34135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
34145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kUploadData, response_data);
34155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a SPDY CONNECT failure through an HTTPS Proxy.
34187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
34195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
34205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
34215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
34225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
34235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "proxy:70".
3425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
34265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
34275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
34305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
34335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY
34353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
34363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                LOWEST));
343790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> get(
343890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
34395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
34415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*connect, 1),
34425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateMockWrite(*get, 3),
34435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
34445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
34467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
34475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
34485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp, 2, ASYNC),
34495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 4),
34505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
34515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
34535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
34545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
34565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
34587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
34605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
34617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
3462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
34635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
34655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
34675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
34685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
34705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
34715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(ttuttle): Anything else to check here?
34735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
34745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
34762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// HTTPS Proxy to different servers.
34777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
34782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
34792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against https proxy server "proxy:70".
3480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
34812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "https://proxy:70"));
34822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
3483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
34842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
3485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
34862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
34882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
34892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("https://www.google.com/");
34902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.load_flags = 0;
34912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
34932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
34942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("https://news.google.com/");
34952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.load_flags = 0;
34962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY.
34983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
34993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                 LOWEST));
35007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp1(
35017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
35022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fetch https://www.google.com/ via HTTP.
35042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char get1[] = "GET / HTTP/1.1\r\n"
35052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Host: www.google.com\r\n"
35062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Connection: keep-alive\r\n\r\n";
35072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get1(
35087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
35092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char resp1[] = "HTTP/1.1 200 OK\r\n"
35102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Content-Length: 1\r\n\r\n";
35112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp1(
35127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
35137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body1(
35147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
35152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> window_update(
351690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
35172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CONNECT to news.google.com:443 via SPDY.
3519116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SpdyHeaderBlock connect2_block;
3520116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
3521116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  connect2_block[spdy_util_.GetPathKey()] = "news.google.com:443";
3522116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  connect2_block[spdy_util_.GetHostKey()] = "news.google.com";
3523116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  spdy_util_.MaybeAddVersionHeader(&connect2_block);
35242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> connect2(
3525116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
3526c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
35277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp2(
35287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
35292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fetch https://news.google.com/ via HTTP.
35312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char get2[] = "GET / HTTP/1.1\r\n"
35322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Host: news.google.com\r\n"
35332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Connection: keep-alive\r\n\r\n";
35342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get2(
35357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
35362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char resp2[] = "HTTP/1.1 200 OK\r\n"
35372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Content-Length: 2\r\n\r\n";
35382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp2(
35397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
35402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body2(
35417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
35422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite spdy_writes[] = {
35442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*connect1, 0),
35452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*wrapped_get1, 2),
35462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*connect2, 5),
35472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*wrapped_get2, 7),
35482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
35492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead spdy_reads[] = {
35512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*conn_resp1, 1, ASYNC),
35522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
35532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_body1, 4, ASYNC),
35542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*conn_resp2, 6, ASYNC),
35552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
35562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_body2, 9, ASYNC),
35572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 0, 10),
35582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
35592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeterministicSocketData spdy_data(
35612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
35622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
35642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
35667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
35682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
35692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl2.was_npn_negotiated = false;
35702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl2.protocol_negotiated = kProtoUnknown;
3571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
35722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl3(ASYNC, OK);
35732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl3.was_npn_negotiated = false;
35742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl3.protocol_negotiated = kProtoUnknown;
3575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
35762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
35782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3580868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
35812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
35822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
35832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The first connect and request, each of their responses, and the body.
35842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(5);
35852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
35872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
35882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
35902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
35912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
35922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
35942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
3595868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
35962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
35972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string response_data;
35992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3600868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
36012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
3603868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
36042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
36052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
36062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The second connect and request, each of their responses, and the body.
36082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(5);
36092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
36102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
36112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
36132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
36142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Even though the SPDY connection is reused, a new tunnelled connection has
36152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to be created, so the socket's load timing looks like a fresh connection.
36162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
36172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The requests should have different IDs, since they each are using their own
36192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // separate stream.
36202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
36212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3622868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
36232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
36242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
36262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// HTTPS Proxy to the same server.
36277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
36282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
36292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against https proxy server "proxy:70".
3630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
36312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "https://proxy:70"));
36322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
3633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
36342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
3635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
36362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
36382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
36392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("https://www.google.com/");
36402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.load_flags = 0;
36412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
36432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
36442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("https://www.google.com/2");
36452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.load_flags = 0;
36462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CONNECT to www.google.com:443 via SPDY.
36483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
36493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                 LOWEST));
36507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp1(
36517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
36522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fetch https://www.google.com/ via HTTP.
36542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char get1[] = "GET / HTTP/1.1\r\n"
36552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Host: www.google.com\r\n"
36562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Connection: keep-alive\r\n\r\n";
36572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get1(
36587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
36592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char resp1[] = "HTTP/1.1 200 OK\r\n"
36602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Content-Length: 1\r\n\r\n";
36612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp1(
36627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
36637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body1(
36647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
36652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> window_update(
366690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
36672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fetch https://www.google.com/2 via HTTP.
36692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char get2[] = "GET /2 HTTP/1.1\r\n"
36702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Host: www.google.com\r\n"
36712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Connection: keep-alive\r\n\r\n";
36722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get2(
36737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
36742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char resp2[] = "HTTP/1.1 200 OK\r\n"
36752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "Content-Length: 2\r\n\r\n";
36762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp2(
36777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
36782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body2(
36797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
36802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite spdy_writes[] = {
36822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*connect1, 0),
36832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*wrapped_get1, 2),
36842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*wrapped_get2, 5),
36852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
36862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead spdy_reads[] = {
36882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*conn_resp1, 1, ASYNC),
36892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
36902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_body1, 4, ASYNC),
36912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
36922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*wrapped_body2, 7, ASYNC),
36932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 0, 8),
36942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
36952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeterministicSocketData spdy_data(
36972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
36982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
37002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
37027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
37042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
37052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl2.was_npn_negotiated = false;
37062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ssl2.protocol_negotiated = kProtoUnknown;
3707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
37082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
37102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3712868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
37132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
37142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
37152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The first connect and request, each of their responses, and the body.
37162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(5);
37172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
37192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
37202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
37222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
37232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
37242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
37262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
3727868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
37282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
37292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string response_data;
37312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3732868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
37332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans.reset();
37342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
3736868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
37372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
37382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
37392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The second request, response, and body.  There should not be a second
37412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // connect.
37422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(3);
37432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
37442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
37452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
37472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
37482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info2);
37492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The requests should have the same ID.
37512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
37522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3753868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
37542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
37552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
37572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Proxy to different servers.
37587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
37592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       HttpsProxySpdyLoadTimingTwoHttpRequests) {
37602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Configure against https proxy server "proxy:70".
3761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
37622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "https://proxy:70"));
37632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingBoundNetLog log;
3764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
37652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
3766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
37672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request1;
37692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.method = "GET";
37702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.url = GURL("http://www.google.com/");
37712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request1.load_flags = 0;
37722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request2;
37742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.method = "GET";
37752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.url = GURL("http://news.google.com/");
37762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request2.load_flags = 0;
37772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // http://www.google.com/
37797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> headers(
37807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
3781116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<SpdyFrame> get1(
3782116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
37837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> get_resp1(
37847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
37857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(
37867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
37872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // http://news.google.com/
37897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> headers2(
37907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
3791116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<SpdyFrame> get2(
3792116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
37937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> get_resp2(
37947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
37957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(
37967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
37972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
37982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite spdy_writes[] = {
37992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*get1, 0),
38002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CreateMockWrite(*get2, 3),
38012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
38022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead spdy_reads[] = {
38042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*get_resp1, 1, ASYNC),
38052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*body1, 2, ASYNC),
38062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*get_resp2, 4, ASYNC),
38072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CreateMockRead(*body2, 5, ASYNC),
38082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, 0, 6),
38092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
38102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeterministicSocketData spdy_data(
38122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
38132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
3814c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
38152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
38177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
3818c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
38192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
38212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3823868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
38242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
38252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
38262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(2);
38272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
38292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
38302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
38322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
38332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
38342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
38352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
38372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
3838868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
38392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
38402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string response_data;
38422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
3843868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
38442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(1);
38452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, callback.WaitForResult());
38462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Delete the first request, so the second one can reuse the socket.
38472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  trans.reset();
38482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans2(
3850868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
38512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
38522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
38532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(2);
38552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
38562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
38572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
38592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
38602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info2);
38612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The requests should have the same ID.
38632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
38642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3865868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
38662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  spdy_data.RunFor(1);
38672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, callback.WaitForResult());
38682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
38692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the challenge-response-retry sequence through an HTTPS Proxy
38717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
38725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
38735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
38745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
38755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the no authentication data flag is set.
38765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
38775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
3879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
38805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://myproxy:70"));
38815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
3882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
3883c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
38845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should use full url
38865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
38875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
38885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
38895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
38905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), this is the request we should
38925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // be issuing -- the final header line contains the credentials.
38935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
38945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
38955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
38965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
38975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
38985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the GET with a 407, using a persistent
39005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
39015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
39025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No credentials.
39035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
39045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
39055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Connection: keep-alive\r\n"),
39065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
39075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
39095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
39105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
39115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
39125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
39135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
39155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
3916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
39175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
3918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
39195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
39215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
3923868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
39245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
39265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
39275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
39295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
39305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
39322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
39332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
39342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
39352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
39375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
3938868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
39395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
39405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
39415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
39425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
39445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
39465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
39475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
39485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
39505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
39515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  load_timing_info = LoadTimingInfo();
39532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
39542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Retrying with HTTP AUTH is considered to be reusing a socket.
39552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReused(load_timing_info);
39562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
39575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
39585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
39595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
39615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
39625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
39635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
39645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
39665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
39675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
39685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
39705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockRead& status, int expected_status) {
39715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
39725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
39735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
39745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
39755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
3977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
3978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
39795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
39815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
39825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
39835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
39845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
39855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
39865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
39885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    status,
39895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
39905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No response body because the test stops reading here.
39915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
39925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
39935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
39955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
3996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
39975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
39985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
39995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4001868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
40025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
40045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
40055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
40075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_status, rv);
40085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::ConnectStatusHelper(
40115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockRead& status) {
40125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelperWithExpectedStatus(
40135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      status, ERR_TUNNEL_CONNECTION_FAILED);
40145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
40175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
40185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
40215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
40225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
40255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
40265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
40295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
40305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
40335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(
40345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
40355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
40385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
40395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
40425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
40435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
40465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
40475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
40505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
40515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
40545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
40555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
40585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
40595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
40625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
40635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
40665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
40675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
40705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
40715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
40745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
40755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
40785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
40795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
40825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
40835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
40845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
40857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
40865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
40875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
40905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
40915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
40945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
40955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
40965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
40985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
40995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
41025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
41035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
41065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
41075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
41105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
41115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
41145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelperWithExpectedStatus(
41155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
41165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ERR_PROXY_AUTH_UNSUPPORTED);
41175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
41205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
41215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
41245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
41255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
41285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
41295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
41325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
41335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
41365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
41375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
41405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
41415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
41445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
41455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
41485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
41495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
41525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(
41535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
41545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
41575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
41585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
41615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
41625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
41655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
41665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
41695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
41705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
41735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
41745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
41775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
41785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
41815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
41825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
41835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the flow when both the proxy server AND origin server require
41855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// authentication. Again, this uses basic auth for both since that is
41865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the simplest to mock.
41877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
41885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
41895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
41905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
41915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
41925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Configure against proxy server "myproxy:70".
4194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
41958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
41965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
41988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
41995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
42015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
42025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
42035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
42045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
42075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 407 Unauthorized\r\n"),
42085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Give a couple authenticate options (only the middle one is actually
42095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // supported).
42105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic invalid\r\n"),  // Malformed.
42115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
42125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
42135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
42145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Large content-length -- won't matter, as connection will be reset.
42155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10000\r\n\r\n"),
42165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
42175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth() the first time, this is the
42205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // request we should be issuing -- the final header line contains the
42215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // proxy's credentials.
42225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
42235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
42245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
42255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
42265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
42275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now the proxy server lets the request pass through to origin server.
42305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The origin server responds with a 401.
42315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
42325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
42335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note: We are using the same realm-name as the proxy server. This is
42345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // completely valid, as realms are unique across hosts.
42355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
42365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
42375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 2000\r\n\r\n"),
42385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),  // Won't be reached.
42395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth() the second time, we should send
42425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the credentials for both the proxy and origin server.
42435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes3[] = {
42445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
42455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
42465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
42475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
42485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
42495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly we get the desired content.
42525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads3[] = {
42535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
42545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
42555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
42565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
42575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
42585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
42605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
42615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
42625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
42635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
42645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
4265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
4266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
4267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
42685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
42705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
42725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
42735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
42755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
42765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
42785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
42795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
42805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
42825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
42845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
42855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
42865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
42885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
42895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
42915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
42925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
42935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
42955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
42975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo2, kBar2), callback3.callback());
42985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
42995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
43015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
43025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
43045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
43055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
43065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
43075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For the NTLM implementation using SSPI, we skip the NTLM tests since we
43095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// can't hook into its internals to cause it to generate predictable NTLM
43105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// authorization headers.
43115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NTLM_PORTABLE)
43125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The NTLM authentication unit tests were generated by capturing the HTTP
43135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// requests and responses using Fiddler 2 and inspecting the generated random
43145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bytes in the debugger.
43155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Enter the correct password and authenticate successfully.
43177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
43185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
43195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
43205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://172.22.68.17/kids/login.aspx");
43214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
43224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Ensure load is not disrupted by flags which suppress behaviour specific
43234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // to other auth schemes.
43244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
43255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
43275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    MockGetHostName);
4328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
43295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
43315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
43325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
43335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
43345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
43355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
43375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
43385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Negotiate and NTLM are often requested together.  However, we only want
43395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
43405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the header that requests Negotiate for this test.
43415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM\r\n"),
43425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: close\r\n"),
43435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
43445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
43455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Missing content -- won't matter, as connection will be reset.
43465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
43475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
43485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
43505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After restarting with a null identity, this is the
43515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // request we should be issuing -- the final header line contains a Type
43525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1 message.
43535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
43545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
43555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
43565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM "
43575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
43585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), we should send a Type 3 message
43605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (the credentials for the origin server).  The second request continues
43615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // on the same connection.
43625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
43635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
43645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
43655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
43665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
43675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
43685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
43695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "ahlhx5I=\r\n\r\n"),
43705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
43715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
43735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The origin server responds with a Type 2 message.
43745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
43755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM "
43765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
43775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
43785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
43795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
43805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
43815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
43825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "BtAAAAAAA=\r\n"),
43835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
43845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
43855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("You are not authorized to view this page\r\n"),
43865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly we get the desired content.
43885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
43895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=utf-8\r\n"),
43905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 13\r\n\r\n"),
43915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Please Login\r\n"),
43925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
43935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
43945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
43965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
43975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
43985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
4399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
4400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
44015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
44035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4405868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
44065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
44085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
44095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
44115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
44125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
44145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
44165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(response == NULL);
44175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
44185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
44205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
44225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              callback2.callback());
44235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
44245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
44265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
44275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
44295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
44315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
44325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
44335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
44355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
44375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
44385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
44405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
44415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
44435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
44445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
44455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(13, response->headers->GetContentLength());
44465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
44475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Enter a wrong password, and then the correct one.
44497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
44505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
44515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
44525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://172.22.68.17/kids/login.aspx");
44535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
44545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
44565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    MockGetHostName);
4457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
44585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
44605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
44615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
44625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
44635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
44645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
44665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
44675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Negotiate and NTLM are often requested together.  However, we only want
44685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
44695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the header that requests Negotiate for this test.
44705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM\r\n"),
44715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: close\r\n"),
44725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
44735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
44745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Missing content -- won't matter, as connection will be reset.
44755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
44765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
44775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
44795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After restarting with a null identity, this is the
44805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // request we should be issuing -- the final header line contains a Type
44815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1 message.
44825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
44835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
44845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
44855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM "
44865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
44875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), we should send a Type 3 message
44895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (the credentials for the origin server).  The second request continues
44905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // on the same connection.
44915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
44925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
44935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
44945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
44955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
44965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
44975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
44985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "4Ww7b7E=\r\n\r\n"),
44995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
45005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
45025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The origin server responds with a Type 2 message.
45035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
45045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM "
45055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
45065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
45075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
45085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
45095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
45105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
45115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "BtAAAAAAA=\r\n"),
45125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
45135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
45145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("You are not authorized to view this page\r\n"),
45155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Wrong password.
45175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
45185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM\r\n"),
45195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Connection: close\r\n"),
45205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
45215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
45225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Missing content -- won't matter, as connection will be reset.
45235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
45245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
45255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes3[] = {
45275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After restarting with a null identity, this is the
45285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // request we should be issuing -- the final header line contains a Type
45295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 1 message.
45305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
45315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
45325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
45335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM "
45345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
45355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After calling trans->RestartWithAuth(), we should send a Type 3 message
45375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (the credentials for the origin server).  The second request continues
45385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // on the same connection.
45395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
45405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: 172.22.68.17\r\n"
45415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
45425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
45435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
45445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
45455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
45465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "+4MUm7c=\r\n\r\n"),
45475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
45485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads3[] = {
45505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The origin server responds with a Type 2 message.
45515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Access Denied\r\n"),
45525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: NTLM "
45535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
45545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
45555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
45565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
45575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
45585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
45595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "BtAAAAAAA=\r\n"),
45605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 42\r\n"),
45615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html\r\n\r\n"),
45625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("You are not authorized to view this page\r\n"),
45635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Lastly we get the desired content.
45655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
45665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=utf-8\r\n"),
45675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 13\r\n\r\n"),
45685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Please Login\r\n"),
45695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
45705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
45715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
45735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
45745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
45755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
45765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
45775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
4578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
4579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
4580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
45815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
45835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4585868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
45865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
45885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
45895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
45915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
45925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
45945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
45965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
45975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
45985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
45995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
46005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enter the wrong password.
46025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
46035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              callback2.callback());
46045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
46055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
46075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
46085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
46105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
46115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
46125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
46135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
46145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
46155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
46165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
46185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(response == NULL);
46195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
46205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback4;
46225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now enter the right password.
46245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
46255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              callback4.callback());
46265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
46275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback4.WaitForResult();
46295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
46305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
46325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback5;
46345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // One more roundtrip
46365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
46375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
46385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback5.WaitForResult();
46405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
46415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
46435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
46445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(13, response->headers->GetContentLength());
46455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
46465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // NTLM_PORTABLE
46475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test reading a server response which has only headers, and no body.
46495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// After some maximum number of bytes is consumed, the transaction should
46505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
46517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
46525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
46535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
46545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
46555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
46565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
46585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
46598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
46605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Respond with 300 kb of headers (we should fail after 256 kb).
46625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string large_headers_string;
46635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FillLargeHeadersString(&large_headers_string, 300 * 1024);
46645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
46665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
46675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
46685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("\r\nBODY"),
46695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
46705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
46715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
46735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
46755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
46775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
46785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
46805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
46815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
46835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response == NULL);
46845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
46855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that we don't try to reuse a TCPClientSocket when failing to
46875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// establish tunnel.
46885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/chromium/issues/detail?id=3772
46897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
46905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       DontRecycleTransportSocketForSSLTunnel) {
46915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
46925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
46935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
46945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
46955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against proxy server "myproxy:70".
4697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
46985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
47005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4702868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
47035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
47055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
47065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
47075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
47085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
47095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 404, using a persistent
47125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection. Usually a proxy would return 501 (not implemented),
47135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or 200 (tunnel established).
47145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
47155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 404 Not Found\r\n"),
47165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
47175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
47185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
47215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
4722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
47235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
47255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
47275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
47285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
47305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
47315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
47335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response == NULL);
47345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
47365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
473790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
47385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the TCPClientSocket was not added back to
47405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the pool.
4741868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
47425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
474390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
47445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure that the socket didn't get recycled after calling the destructor.
4745868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
47465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
47475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that we recycle a socket after reading all of the response body.
47497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
47505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
47515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
47525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
47535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
47545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
47565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4758868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
47595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
47615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // A part of the response body is received with the response headers.
47625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
47635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The rest of the response body is received in two parts.
47645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("lo"),
47655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(" world"),
47665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("junk"),  // Should not be read!!
47675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
47685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
47695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
47725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
47745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
47765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
47775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
47795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
47805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
47825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
47835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4784868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
47855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string status_line = response->headers->GetStatusLine();
47865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", status_line);
47875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4788868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
47895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
47915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
47925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
47935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
47945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
47965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
479790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
47985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
47995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4800868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
48015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
48025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that we recycle a SSL socket after reading all of the response
48045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// body.
48057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
48065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
48075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
48085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
48095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
48105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
48125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
48135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
48145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
48155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
48165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
48185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
48195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 11\r\n\r\n"),
48205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
48215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
48225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
48235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
4825c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
48265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
48285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
4829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
48305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
48325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4833c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
48342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4835868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
48365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
48385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
48405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
48415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
48435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
4844868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
48455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
48465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4847868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
48485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
48505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
48515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
48525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
48535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
48555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
485690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
48575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4859868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
48605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
48615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Grab a SSL socket, use it, and put it back into the pool.  Then, reuse it
48635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from the pool and make sure that we recover okay.
48647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
48655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
48665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
48675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
48685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
48695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
48715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
48725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
48735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
48745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
48755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
48765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
48775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
48785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
48805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
48815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 11\r\n\r\n"),
48825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
48835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
48845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0)   // EOF
48855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
48865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
48885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
4889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
48915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
48935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
48945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
48955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
4896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
4897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
48985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
48995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
49005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
49022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4903868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
49045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
49065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
49085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
49095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
49115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
4912868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
49135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
49145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
49165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
49185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
49195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
49205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
49215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
49235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
492490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
49255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4927868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
49285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now start the second transaction, which should reuse the previous socket.
49305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4931868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
49325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
49345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
49365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
49375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
49395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
4940868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
49415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
49425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4943868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
49445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
49465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
49475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
49485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
49505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
495190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
49525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
4954868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
49555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
49565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that we recycle a socket after a zero-length response.
49585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/9880
49597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
49605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
49615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
49625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
49635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
49645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     "e=17259,18167,19592,19773,19981,20133,20173,20233&"
49655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     "rt=prt.2642,ol.2649,xjs.2951");
49665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
49675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
49695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
4971868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
49725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
49745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 204 No Content\r\n"
49755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 0\r\n"
49765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Type: text/html\r\n\r\n"),
49775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("junk"),  // Should not be read!!
49785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
49795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
49805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
4982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
49835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
49855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
49875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
49885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
49905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
49915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
49935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
49945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
49965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string status_line = response->headers->GetStatusLine();
49975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
49985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4999868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
50005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
50025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
50035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
50045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", response_data);
50055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.  This is necessary because idle sockets are
50075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // added to the connection pool asynchronously with a PostTask.
500890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
50095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We now check to make sure the socket was added back to the pool.
5011868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
50125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
50135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
50152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
50162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(new UploadBytesElementReader("foo", 3));
501768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
50182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
50195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request[2];
50205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 1: a GET request that succeeds.  The socket is recycled
50215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // after use.
50225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[0].method = "GET";
50235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[0].url = GURL("http://www.google.com/");
50245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[0].load_flags = 0;
50255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 2: a POST request.  Reuses the socket kept alive from
50265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction 1.  The first attempts fails when writing the POST data.
50275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This causes the transaction to retry with a new socket.  The second
50285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // attempt succeeds.
50295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[1].method = "POST";
50305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[1].url = GURL("http://www.google.com/login.cgi");
50312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request[1].upload_data_stream = &upload_data_stream;
50325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request[1].load_flags = 0;
50335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5034c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
50355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first socket is used for transaction 1 and the first attempt of
50375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction 2.
50385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The response of transaction 1.
50405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
50415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
50425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
50435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
50445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
50455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The mock write results of transaction 1 and the first attempt of
50465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction 2.
50475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
50485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 64),  // GET
50495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 93),  // POST
50505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED),  // POST data
50515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
50525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
50535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
50545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The second socket is used for the second attempt of transaction 2.
50565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The response of transaction 2.
50585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
50595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
50605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("welcome"),
50615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
50625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
50635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The mock write results of the second attempt of transaction 2.
50645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
50655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 93),  // POST
50665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(SYNCHRONOUS, 3),  // POST data
50675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
50685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
50695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
50705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5071c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
5072c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
50735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* kExpectedResponseData[] = {
50755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "hello world", "welcome"
50765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
50775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; ++i) {
50795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5080868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
50815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
50835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
50855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
50865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
50885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
50895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
50915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
50925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5093868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response->headers.get() != NULL);
50945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
50955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
50965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string response_data;
50975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = ReadTransaction(trans.get(), &response_data);
50985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
50995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kExpectedResponseData[i], response_data);
51005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
51015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
51025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth when there is
51045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// an identity in the URL. The request should be sent as normal, but when
51055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it fails the identity from the URL is used to answer the challenge.
51067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
51075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
51085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
51095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://foo:b@r@www.google.com/");
51105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = LOAD_NORMAL;
51115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
51135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
51148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
51155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password contains an escaped character -- for this test to pass it
51175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will need to be unescaped by HttpNetworkTransaction.
51185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("b%40r", request.url.password());
51195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
51215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
51225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
51235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
51245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
51255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
51275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
51285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
51295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
51305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
51315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
51325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the challenge above, the transaction will be restarted using the
51345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // identity from the url (foo, b@r) to answer the challenge.
51355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
51365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
51375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
51385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
51395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
51405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
51415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
51435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
51445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
51455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
51465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
51475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
51495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
51505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
51515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
5152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
5153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
51545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
51565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
51575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
51585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
51595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
51605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
51615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
51635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
51645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
51655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
51665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
51675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
51685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
51705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
51715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There is no challenge info, since the identity in URL worked.
51735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
51745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
51765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.
517890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
51795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
51805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth when there is an
51825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// incorrect identity in the URL. The identity from the URL should be used only
51835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// once.
51847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
51855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
51865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
51875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: the URL has a username:password in it.  The password "baz" is
51885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // wrong (should be "bar").
51895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://foo:baz@www.google.com/");
51905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = LOAD_NORMAL;
51925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
51945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
51958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
51965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
51985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
51995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
52005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
52015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
52025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
52045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
52055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
52065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
52075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
52085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
52095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the challenge above, the transaction will be restarted using the
52115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // identity from the url (foo, baz) to answer the challenge.
52125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
52135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
52145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
52155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
52165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
52175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
52185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
52205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
52215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
52225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
52235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
52245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
52255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the challenge above, the transaction will be restarted using the
52275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // identity supplied by the user (foo, bar) to answer the challenge.
52285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes3[] = {
52295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
52305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
52315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
52325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
52335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
52345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads3[] = {
52365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
52375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
52385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
52395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
52405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
52425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
52435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
52445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
52455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
52465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
5247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
5248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
5249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
52505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
52525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
52545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
52555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
52575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
52585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->IsReadyToRestartForAuth());
52605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
52615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
52625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
52635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
52645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
52655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
52665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
52685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
52695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
52705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
52725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
52735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback3.callback());
52745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
52755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
52765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
52775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
52785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
52805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
52815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There is no challenge info, since the identity worked.
52835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
52845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
52865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty the current queue.
528890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
52895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
52905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
52924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Test the request-challenge-retry sequence for basic auth when there is a
52934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// correct identity in the URL, but its use is being suppressed. The identity
52944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// from the URL should never be used.
52954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
52964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  HttpRequestInfo request;
52974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.method = "GET";
52984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.url = GURL("http://foo:bar@www.google.com/");
52994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
53004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
53024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
53038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
53044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MockWrite data_writes1[] = {
53064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
53074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Host: www.google.com\r\n"
53084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
53094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
53104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MockRead data_reads1[] = {
53124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead("HTTP/1.0 401 Unauthorized\r\n"),
53134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
53144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead("Content-Length: 10\r\n\r\n"),
53154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_FAILED),
53164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
53174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // After the challenge above, the transaction will be restarted using the
53194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // identity supplied by the user, not the one in the URL, to answer the
53204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // challenge.
53214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MockWrite data_writes3[] = {
53224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
53234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Host: www.google.com\r\n"
53244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Connection: keep-alive\r\n"
53254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
53264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
53274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  MockRead data_reads3[] = {
53294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
53304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
53314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
53324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
53334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
53354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
53364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
53374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
53384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
53394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
53404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestCompletionCallback callback1;
53424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
53434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
53444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  rv = callback1.WaitForResult();
53454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(OK, rv);
53464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
53474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
53494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
53504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
53514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestCompletionCallback callback3;
53534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  rv = trans->RestartWithAuth(
53544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      AuthCredentials(kFoo, kBar), callback3.callback());
53554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
53564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  rv = callback3.WaitForResult();
53574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(OK, rv);
53584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(trans->IsReadyToRestartForAuth());
53594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  response = trans->GetResponseInfo();
53614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
53624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // There is no challenge info, since the identity worked.
53644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
53654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
53664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Empty the current queue.
53684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
53694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
53704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
53715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that previously tried username/passwords for a realm get re-used.
53727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
5373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
53745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 1: authenticate (foo, bar) on MyRealm1
53765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
53775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
53785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
53795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/z");
53805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
53815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5383868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
53845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
53865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z HTTP/1.1\r\n"
53875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
53885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n\r\n"),
53895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
53905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
53925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
53935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
53945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
53955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
53965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
53975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization (username=foo, password=bar)
53995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
54005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z HTTP/1.1\r\n"
54015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
54025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
54035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
54045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
54055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
54075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
54085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
54095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
54105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
54115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
54125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
54145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
54155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
54165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
5417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
54195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
54215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
54235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
54245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
54265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
54275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
54295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
54305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
54315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
54335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(
54355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AuthCredentials(kFoo, kBar), callback2.callback());
54365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
54375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
54395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
54405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response = trans->GetResponseInfo();
54425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
54435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
54445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
54455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
54465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
54485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 2: authenticate (foo2, bar2) on MyRealm2
54505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
54515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
54525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
54535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note that Transaction 1 was at /x/y/z, so this is in the same
54545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // protection space as MyRealm1.
54555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/a/b");
54565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
54575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5459868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
54605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
54625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
54635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
54645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
54655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // Send preemptive authorization for MyRealm1
54665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
54675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
54685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The server didn't like the preemptive authorization, and
54705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // challenges us for a different realm (MyRealm2).
54715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
54725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
54735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
54745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
54755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
54765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
54775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
54795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
54805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
54815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
54825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
54835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
54845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
54855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
54875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
54885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
54895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
54905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
54915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
54925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
54945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
54955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
54965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
5497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
54995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
55015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
55035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
55045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
55065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
55075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
55095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
55105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response->auth_challenge.get());
55115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(response->auth_challenge->is_proxy);
55125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("www.google.com:80",
55135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              response->auth_challenge->challenger.ToString());
55145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
55155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("basic", response->auth_challenge->scheme);
55165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
55185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(
55205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AuthCredentials(kFoo2, kBar2), callback2.callback());
55215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
55225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
55245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
55255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response = trans->GetResponseInfo();
55275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
55285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
55295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
55305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
55315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
55335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 3: Resend a request in MyRealm's protection space --
55355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // succeed with preemptive authorization.
55365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
55375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
55385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
55395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/z2");
55405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
55415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5543868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
55445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
55465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
55475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
55485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
55495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // The authorization for MyRealm1 gets sent preemptively
55505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                // (since the url is in the same protection space)
55515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
55525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
55535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the preemptive authorization
55555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
55565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
55575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
55585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
55595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
55605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
55625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
5563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
55645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
55665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
55685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
55695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
55715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
55725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
55745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
55755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
55775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
55785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
55795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
55815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 4: request another URL in MyRealm (however the
55835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // url is not known to belong to the protection space, so no pre-auth).
55845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
55855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
55865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
55875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/1");
55885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
55895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5591868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
55925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
55945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/1 HTTP/1.1\r\n"
55955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
55965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n\r\n"),
55975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
55985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
56005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
56015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
56025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
56035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
56045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization from MyRealm's cache.
56075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
56085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/1 HTTP/1.1\r\n"
56095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
56105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
56115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
56125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
56155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
56165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
56175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
56185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
56195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
56225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
56235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
56245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
5625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
56275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
56295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
56315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
56325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
56345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
56355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(trans->IsReadyToRestartForAuth());
56375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
56385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
56395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
56405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
56415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
56425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(trans->IsReadyToRestartForAuth());
56435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
56455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
56465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
56475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
56485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
56495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
56515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 5: request a URL in MyRealm, but the server rejects the
56535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cached identity. Should invalidate and re-prompt.
56545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
56555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
56565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
56575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/p/q/t");
56585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
56595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5661868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
56625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
56645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /p/q/t HTTP/1.1\r\n"
56655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
56665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n\r\n"),
56675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
56705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
56715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
56725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
56735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
56745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization from cache for MyRealm.
56775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
56785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /p/q/t HTTP/1.1\r\n"
56795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
56805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
56815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
56825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever rejects the authorization.
56855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
56865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
56875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
56885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 10000\r\n\r\n"),
56895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, ERR_FAILED),
56905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
56915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // At this point we should prompt for new credentials for MyRealm.
56935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Restart with username=foo3, password=foo4.
56945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes3[] = {
56955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /p/q/t HTTP/1.1\r\n"
56965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
56975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
56985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
56995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
57005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
57025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads3[] = {
57035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
57045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
57055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
57065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
57075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
57095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
57105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
57115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
57125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
57135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes3, arraysize(data_writes3));
5714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
5716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data3);
57175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
57195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
57215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
57225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
57245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
57255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(trans->IsReadyToRestartForAuth());
57275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
57285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
57295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
57305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
57315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
57325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(trans->IsReadyToRestartForAuth());
57335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
57355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
57365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
57375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback3;
57395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(
57415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AuthCredentials(kFoo3, kBar3), callback3.callback());
57425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
57435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback3.WaitForResult();
57455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
57465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response = trans->GetResponseInfo();
57485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
57495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
57505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
57515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
57525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
57535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that nonce count increments when multiple auth attempts
57555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are started with the same nonce.
57567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
57575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerDigest::Factory* digest_factory =
57585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new HttpAuthHandlerDigest::Factory();
57595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
57605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
57615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  digest_factory->set_nonce_generator(nonce_generator);
5762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.http_auth_handler_factory.reset(digest_factory);
5763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
57645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 1: authenticate (foo, bar) on MyRealm1
57665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
57675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
57685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
57695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/z");
57705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
57715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5773868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
57745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
57765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z HTTP/1.1\r\n"
57775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
57785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n\r\n"),
57795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
57805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
57825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 401 Unauthorized\r\n"),
57835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
57845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
57855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
57865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
57875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Resend with authorization (username=foo, password=bar)
57895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes2[] = {
57905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/z HTTP/1.1\r\n"
57915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
57925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
57935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Digest username=\"foo\", realm=\"digestive\", "
57945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
57955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
57965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
57975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
57985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
57995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
58005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads2[] = {
58015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
58025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
58035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
58045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
58065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
58075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
58085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes2, arraysize(data_writes2));
5809c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
5810c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data2);
58115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
58135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
58155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
58165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
58185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
58195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
58215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
58225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
58235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback2;
58255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithAuth(
58275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AuthCredentials(kFoo, kBar), callback2.callback());
58285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
58295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback2.WaitForResult();
58315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
58325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    response = trans->GetResponseInfo();
58345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
58355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
58365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
58375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ------------------------------------------------------------------------
58395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transaction 2: Request another resource in digestive's protection space.
58415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This will preemptively add an Authorization header which should have an
58425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "nc" value of 2 (as compared to 1 in the first use.
58435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
58445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
58455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
58465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Note that Transaction 1 was at /x/y/z, so this is in the same
58475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // protection space as digest.
58485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL("http://www.google.com/x/y/a/b");
58495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
58505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
5852868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
58535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite data_writes1[] = {
58555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
58565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Host: www.google.com\r\n"
58575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Connection: keep-alive\r\n"
58585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "Authorization: Digest username=\"foo\", realm=\"digestive\", "
58595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
58605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
58615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
58625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
58635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Sever accepts the authorization.
58655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead data_reads1[] = {
58665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("HTTP/1.0 200 OK\r\n"),
58675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead("Content-Length: 100\r\n\r\n"),
58685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead(SYNCHRONOUS, OK),
58695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
58705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
58725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   data_writes1, arraysize(data_writes1));
5873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->AddSocketDataProvider(&data1);
58745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback1;
58765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
58785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
58795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback1.WaitForResult();
58815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
58825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
58845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
58855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(response->auth_challenge.get() == NULL);
58865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
58875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
58885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the ResetStateForRestart() private method.
58907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
58915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a transaction (the dependencies aren't important).
58928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
58935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans(
58948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
58955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setup some state (which we expect ResetStateForRestart() will clear).
58975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans->read_buf_ = new IOBuffer(15);
58985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans->read_buf_len_ = 15;
58995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans->request_headers_.SetHeader("Authorization", "NTLM");
59005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setup state in response_
59025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpResponseInfo* response = &trans->response_;
59035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->auth_challenge = new AuthChallengeInfo();
59045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->ssl_info.cert_status = static_cast<CertStatus>(-1);  // Nonsensical.
59055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->response_time = base::Time::Now();
59065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response->was_cached = true;  // (Wouldn't ever actually be true...)
59075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  { // Setup state for response_.vary_data
59095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
59105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
59115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::replace(temp.begin(), temp.end(), '\n', '\0');
59125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
59135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.extra_headers.SetHeader("Foo", "1");
59145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.extra_headers.SetHeader("bar", "23");
5915868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
59165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
59175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cause the above state to be reset.
59195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans->ResetStateForRestart();
59205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the state that needed to be reset, has been reset.
59225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->read_buf_.get() == NULL);
59235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, trans->read_buf_len_);
59245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans->request_headers_.IsEmpty());
59255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
59265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() == NULL);
59275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_cached);
59285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, response->ssl_info.cert_status);
59295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->vary_data.is_valid());
59305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
59315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections to a site with a bad certificate
59337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
59345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
59355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
59365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
59375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
59385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
59405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
59418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
59425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
59445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
59455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
59465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
59475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
59485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
59505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
59515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
59525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
59535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
59545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
59555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider ssl_bad_certificate;
59575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
59585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
59595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
59605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
59615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
5963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
5964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
5965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
59665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
59685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
59705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
59715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
59735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
59745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartIgnoringLastError(callback.callback());
59765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
59775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
59795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
59805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
59825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
59845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
59855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
59865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections to a site with a bad certificate, going through a
59885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// proxy
59897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
5990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
59915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
59935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
59945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
59955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
59965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite proxy_writes[] = {
59985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
59995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
60005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
60015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
60025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead proxy_reads[] = {
60045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
60055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
60065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
60075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
60095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
60105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
60115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
60125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
60135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
60145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
60155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
60165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
60185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
60195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
60205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
60215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
60225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
60235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
60245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider ssl_bad_certificate(
60265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      proxy_reads, arraysize(proxy_reads),
60275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      proxy_writes, arraysize(proxy_writes));
60285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
60295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
60305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
60315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
60325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6033c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6034c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6035c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6036c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
60375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
60395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; i++) {
6041c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->ResetNextMockIndexes();
60425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
60445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
60458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
60465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(&request, callback.callback(), BoundNetLog());
60485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
60495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
60515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
60525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartIgnoringLastError(callback.callback());
60545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
60555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
60575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(OK, rv);
60585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const HttpResponseInfo* response = trans->GetResponseInfo();
60605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
60625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(100, response->headers->GetContentLength());
60635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
60645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
60655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections to a site, going through an HTTPS proxy
60687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
6069c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
60702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
60712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
6072c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
60735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
60755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
60765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
60775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
60785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
60805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
60815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
60825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
60835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
60845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
60855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
60865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
60875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
60895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
60905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
60915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
60925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
60935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
60945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
60955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
60975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
60985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
60995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider tunnel_ssl(ASYNC, OK);  // SSL through the tunnel
61005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
61045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
61065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
61085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
61098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
61105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
61125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
61135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
61155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
61165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
61175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
61195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
61215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
61225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
61235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
61242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
61252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
61262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
61272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
61282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
61295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
61305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test an HTTPS Proxy's ability to redirect a CONNECT request
61327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
6133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
61342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
61352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
6136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
61375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
61395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
61405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
61415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
61425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
61445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
61455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
61465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
61475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
61485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
61505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 302 Redirect\r\n"),
61515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Location: http://login.example.com/\r\n"),
61525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 0\r\n\r\n"),
61535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
61545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
61555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
61575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
61585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
61595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
61625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
61645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
61665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
61678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
61685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
61705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
61715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
61735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
61745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
61755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
61775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
61785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(302, response->headers->response_code());
61795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
61805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsRedirect(&url));
61815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://login.example.com/", url);
61822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
61832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // In the case of redirects from proxies, HttpNetworkTransaction returns
61842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // timing for the proxy connection instead of the connection to the host,
61852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // and no send / receive times.
61862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
61872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
61882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
61892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
61902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.socket_reused);
61912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
61922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
61932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
61942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_start,
61952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.proxy_resolve_end);
61962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LE(load_timing_info.proxy_resolve_end,
61972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            load_timing_info.connect_timing.connect_start);
61982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExpectConnectTimingHasTimes(
61992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      load_timing_info.connect_timing,
62002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
62012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
62022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.send_start.is_null());
62032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.send_end.is_null());
62042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
62055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
62065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
62087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
6209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
62105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://proxy:70"));
62115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
62135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
62145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
62155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
62165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
62183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                             LOWEST));
621990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> goaway(
622090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
62215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
62225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
6223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
62245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* const kExtraHeaders[] = {
62275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "location",
62285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "http://login.example.com/",
62295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(
62317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
62325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 arraysize(kExtraHeaders)/2, 1));
62335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
62345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
62355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 2),  // EOF
62365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data(
62395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
62405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads),
62415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_writes, arraysize(data_writes));
62425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
62437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy_ssl.SetNextProto(GetParam());
62445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
62475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
62495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
62515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
62528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
62535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
62555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
62565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
62585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
62595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
62605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
62625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(302, response->headers->response_code());
62645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
62655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsRedirect(&url));
62665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://login.example.com/", url);
62675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
62685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that an HTTPS proxy's response to a CONNECT request is filtered.
62707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
62715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ErrorResponseToHttpsConnectViaHttpsProxy) {
6272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
62735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://proxy:70"));
62745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
62765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
62775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
62785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
62795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
62815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
62825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
62835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
62845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
62875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 404 Not Found\r\n"),
62885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 23\r\n\r\n"),
62895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("The host does not exist"),
62905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
62915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
62925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
62945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
62955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
62965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
62995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
63015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
63035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
63048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
63055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
63075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
63085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
63105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
63115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(ttuttle): Anything else to check here?
63135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
63145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that a SPDY proxy's response to a CONNECT request is filtered.
63167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
63175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ErrorResponseToHttpsConnectViaSpdyProxy) {
6318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
6319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)     ProxyService::CreateFixed("https://proxy:70"));
63205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
63225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
63235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
63245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
63255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
63273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                             LOWEST));
632890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> rst(
632990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
63305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
63315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
63325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
63335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
63345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char* const kExtraHeaders[] = {
63365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "location",
63375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "http://login.example.com/",
63385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
63395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(
63407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
63415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 arraysize(kExtraHeaders)/2, 1));
63425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> body(
63437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(
63447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          1, "The host does not exist", 23, true));
63455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
63465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
63475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body.get(), 2, SYNCHRONOUS),
63485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 4),  // EOF
63495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
63505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data(
63525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
63535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads),
63545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_writes, arraysize(data_writes));
63555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
63567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy_ssl.SetNextProto(GetParam());
63575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
63605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
63625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
63645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
63658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
63665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
63685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
63695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
63715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
63725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(ttuttle): Anything else to check here?
63745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
63755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the request-challenge-retry sequence for basic auth, through
63775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a SPDY proxy over a single SPDY session.
63787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
63795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
63805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
63815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
63825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the no authentication data flag is set.
63835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
63845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
6386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
63872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
63885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
6389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
6390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
63915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
63933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
63943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                            LOWEST));
639590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> rst(
639690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
63975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), this is the request we should
63995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be issuing -- the final header line contains the credentials.
64005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kAuthCredentials[] = {
64015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "proxy-authorization", "Basic Zm9vOmJhcg==",
64025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
640390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
64043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
64055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fetch https://www.google.com/ via HTTP
64065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char get[] = "GET / HTTP/1.1\r\n"
64075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Host: www.google.com\r\n"
64085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Connection: keep-alive\r\n\r\n";
64095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get(
64107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
64115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
64135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req, 1, ASYNC),
64145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*rst, 4, ASYNC),
64155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*connect2, 5),
64165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*wrapped_get, 8),
64175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
64185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The proxy responds to the connect with a 407, using a persistent
64205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection.
6421116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const char* const kAuthStatus = "407";
64225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kAuthChallenge[] = {
64235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "proxy-authenticate", "Basic realm=\"MyRealm1\"",
64245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6426116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
64275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp(
64297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
64305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char resp[] = "HTTP/1.1 200 OK\r\n"
64315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 5\r\n\r\n";
64325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_get_resp(
64347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
64355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body(
64367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
64375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
64385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_auth_resp, 2, ASYNC),
64395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_resp, 6, ASYNC),
64405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_get_resp, 9, ASYNC),
64415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body, 10, ASYNC),
64425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK, 11),  // EOF.  May or may not be read.
64435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
64445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
64465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
64475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
6448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
64495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Negotiate SPDY to the proxy
64505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy(ASYNC, OK);
64517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy.SetNextProto(GetParam());
6452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
64535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Vanilla SSL to the server
64545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider server(ASYNC, OK);
6455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
64565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
64585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
6460868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
64615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
64635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
64645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
64665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
64675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
64685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
64695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
64705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
64715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
64725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
64735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
64745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
64755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
64765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
64785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
6479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_FALSE(response->headers.get() == NULL);
64805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(407, response->headers->response_code());
64815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
64825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() != NULL);
64835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
64845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
64865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
64885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              callback2.callback());
64895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
64905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
64925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
64935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
64955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
64965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
64985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
64995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, response->headers->GetContentLength());
65005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
65015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The password prompt info should not be set.
65035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
65045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
65062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
65072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
65082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
65092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
65105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
65115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
65125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
65135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that an explicitly trusted SPDY proxy can push a resource from an
65155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// origin that is different from that of its associated resource.
65167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
65175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
65185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo push_request;
65195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
65215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
65225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  push_request.method = "GET";
65235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  push_request.url = GURL("http://www.another-origin.com/foo.dat");
65245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
6526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
65272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
65285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
6529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
65305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable cross-origin push.
6532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.trusted_spdy_proxy = "myproxy:70";
65335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
65355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
653690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> stream1_syn(
653790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
65385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
654090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CreateMockWrite(*stream1_syn, 1, ASYNC),
65415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
65425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
65447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
65455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
65477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
65485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
65507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
65515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    0,
65525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    2,
65535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    1,
65545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    "http://www.another-origin.com/foo.dat"));
6555eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const char kPushedData[] = "pushed";
6556eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<SpdyFrame> stream2_body(
6557eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      spdy_util_.ConstructSpdyBodyFrame(
6558eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          2, kPushedData, strlen(kPushedData), true));
65595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
65615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream1_reply, 2, ASYNC),
65625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream2_syn, 3, ASYNC),
65635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream1_body, 4, ASYNC),
6564eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    CreateMockRead(*stream2_body, 5, ASYNC),
65655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
65665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
65675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
65695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
65705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
6571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
65725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Negotiate SPDY to the proxy
65735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy(ASYNC, OK);
65747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy.SetNextProto(GetParam());
6575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
65765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
6578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
65795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
65805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), log.bound());
65815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
65825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
65845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
65855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
65865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> push_trans(
6588868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6589868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = push_trans->Start(&push_request, callback.callback(), log.bound());
65905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
65915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
65935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
65945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
65955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
65975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
65985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
66005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
66015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
66035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
66045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
66055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
66065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
66082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
66092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
66102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
66112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
66125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify the pushed stream.
6613868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(push_response->headers.get() != NULL);
66145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, push_response->headers->response_code());
66155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(push_trans.get(), &response_data);
66175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
66185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("pushed", response_data);
66195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo push_load_timing_info;
66212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
66222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReusedWithPac(push_load_timing_info);
66232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The transactions should share a socket ID, despite being for different
66242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // origins.
66252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(load_timing_info.socket_log_id,
66262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            push_load_timing_info.socket_log_id);
66272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
66285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
66295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  push_trans.reset();
66305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
66315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
66325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
66347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
66355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
66365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
66385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
66395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Configure against https proxy server "myproxy:70".
6641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
66425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://myproxy:70"));
66435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
6644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
66455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable cross-origin push.
6647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.trusted_spdy_proxy = "myproxy:70";
66485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
66505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> stream1_syn(
665290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
66535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame> push_rst(
665590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
66565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
66585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*stream1_syn, 1, ASYNC),
66595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*push_rst, 4),
66605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
66615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
66637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
66645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
66667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
66675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpdyFrame>
66697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
66705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    0,
66715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    2,
66725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    1,
66735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    "https://www.another-origin.com/foo.dat"));
66745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
66765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream1_reply, 2, ASYNC),
66775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream2_syn, 3, ASYNC),
66785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*stream1_body, 5, ASYNC),
66795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
66805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
66815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
66835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
66845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
6685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
66865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Negotiate SPDY to the proxy
66875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider proxy(ASYNC, OK);
66887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  proxy.SetNextProto(GetParam());
6689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
66905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
6692868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
66935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
66945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), log.bound());
66955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
66965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
66975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
66985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
66995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
67005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
67025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
67035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
67055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
67065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
67085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
67095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
67105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
67115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();
67135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  session->CloseAllConnections();
67145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
67155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections to a site with a bad certificate, going through an
67175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HTTPS proxy
67187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
6719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed(
67205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://proxy:70"));
67215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
67235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
67245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
67255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
67265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attempt to fetch the URL from a server with a bad cert
67285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite bad_cert_writes[] = {
67295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
67305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
67315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
67325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
67335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead bad_cert_reads[] = {
67355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
67365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
67375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
67385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attempt to fetch the URL with a good cert
67405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite good_data_writes[] = {
67415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
67425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
67435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
67445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
67455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
67465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
67475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
67485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead good_cert_reads[] = {
67505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
67515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
67525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
67535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
67545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
67555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
67565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider ssl_bad_certificate(
67585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bad_cert_reads, arraysize(bad_cert_reads),
67595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bad_cert_writes, arraysize(bad_cert_writes));
67605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
67615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                good_data_writes, arraysize(good_data_writes));
67625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
67635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
67645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SSL to the proxy, then CONNECT request, then SSL with bad certificate
6766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
67695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SSL to the proxy, then CONNECT request, then valid SSL certificate
6771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
6773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
67745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
67765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
67785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
67798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
67805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
67825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
67835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
67855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
67865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartIgnoringLastError(callback.callback());
67885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
67895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
67915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
67925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
67945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
67965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
67975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
67985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
67997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
68005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
68015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
68025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
68035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
68045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  "Chromium Ultra Awesome X Edition");
68055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
68075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
68088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
68095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
68115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
68125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
68135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
68145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
68155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
68185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
68195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
68205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
68215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
68225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
68235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
68265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
68285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
68305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
68325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
68335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
68355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
68365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
68375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
68395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
68405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
68415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
68425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
68435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  "Chromium Ultra Awesome X Edition");
68445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
68468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
68475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
68488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
68495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
68515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
68525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
68535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
68545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
68555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
68575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Return an error, so the transaction stops here (this test isn't
68585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // interested in the rest).
68595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
68605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
68615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Proxy-Connection: close\r\n\r\n"),
68625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
68655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
68675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
68695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
68715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
68725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
68745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
68755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
68765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
68785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
68795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
68805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
68815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
68825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
68835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  "http://the.previous.site.com/");
68845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
68865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
68878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
68885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
68905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
68915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
68925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
68935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Referer: http://the.previous.site.com/\r\n\r\n"),
68945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
68955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
68975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
68985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
68995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
69005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
69015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
69025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
69055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6906c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
69075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
69095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
69115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
69125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
69145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
69155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
69165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
69185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
69195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
69205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
69215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
69235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
69248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
69255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
69275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("POST / HTTP/1.1\r\n"
69285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
69295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
69305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
69315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
69345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
69355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
69365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
69375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
69385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
69395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
69425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
69445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
69465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
69485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
69495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
69515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
69525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
69535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
69555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
69565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "PUT";
69575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
69585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
69605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
69618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
69625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
69645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("PUT / HTTP/1.1\r\n"
69655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
69665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
69675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
69685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
69715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
69725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
69735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
69745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
69755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
69765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
69775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
69795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
6980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
69815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
69835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
69855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
69865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
69885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
69895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
69905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
69925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
69935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "HEAD";
69945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
69955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
69975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
69988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
69995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
70015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("HEAD / HTTP/1.1\r\n"
70025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
70035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
70045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Content-Length: 0\r\n\r\n"),
70055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
70065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
70085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
70095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
70105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
70115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
70125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
70135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
70145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
70165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7017c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
70185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
70205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
70225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
70235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
70255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
70265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
70275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
70295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
70305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
70315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
70325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = LOAD_BYPASS_CACHE;
70335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
70355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
70368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
70375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
70395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
70405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
70415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
70425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Pragma: no-cache\r\n"
70435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Cache-Control: no-cache\r\n\r\n"),
70445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
70455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
70475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
70485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
70495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
70505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
70515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
70525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
70535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
70555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7056c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
70575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
70595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
70615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
70625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
70645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
70655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
70665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
70685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       BuildRequest_CacheControlValidateCache) {
70695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
70705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
70715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
70725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = LOAD_VALIDATE_CACHE;
70735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
70755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
70768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
70775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
70795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
70805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
70815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
70825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Cache-Control: max-age=0\r\n\r\n"),
70835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
70845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
70865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
70875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
70885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
70895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
70905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
70915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
70925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
70945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7095c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
70965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
70985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
71005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
71015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
71035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
71045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
71055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
71075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
71085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
71095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
71105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader("FooHeader", "Bar");
71115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
71135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
71148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
71155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
71175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
71185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
71195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
71205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "FooHeader: Bar\r\n\r\n"),
71215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
71245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
71255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
71265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
71275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
71285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
71295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
71325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
71345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
71365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
71385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
71395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
71415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
71425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
71435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
71455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
71465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
71475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
71485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader("referer", "www.foo.com");
71495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader("hEllo", "Kitty");
71505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.extra_headers.SetHeader("FoO", "bar");
71515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
71535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
71548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
71555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
71575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
71585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
71595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
71605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "referer: www.foo.com\r\n"
71615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "hEllo: Kitty\r\n"
71625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "FoO: bar\r\n\r\n"),
71635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
71665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
71675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
71685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
71695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
71705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
71715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
71725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
71745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
71765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
71785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
71805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
71815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
71835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
71845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
71855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
71875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
71885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
71895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
71905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
71915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
71932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
71942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
7195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
71965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
71985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
71998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
72005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
72025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
72035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
72055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
72065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
72075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
72085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
72095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
72105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
72125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
72135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
72145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
72155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Payload"),
72165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
72175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
72185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
72205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
72225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
72245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
72265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
72275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
72295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
72305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
72325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
72335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
72352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
72362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
72372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
72382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_text;
72405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
72415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
72425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Payload", response_text);
72435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
72445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
72465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
72475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
72485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
72495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
72505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
72522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
72532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
7254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
72555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
72575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
72588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
72595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
72615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
72625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
72645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
72655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              arraysize(write_buffer)),
72665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
72675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
72685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
72695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
72705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
72725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
72735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(read_buffer)),
72745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
72755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
72765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Payload"),
72775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
72785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
72795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
72815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
72835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
7285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
72862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
72882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
72902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
72912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = callback.WaitForResult();
72932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
72942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
72962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
72972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
72982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
72992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
73012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
73022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string response_text;
73042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
73052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, rv);
73062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ("Payload", response_text);
73072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
73082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
73102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo request;
73112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.method = "GET";
73122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.url = GURL("http://www.google.com/");
73132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.load_flags = 0;
73142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
73162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixed("socks4://myproxy:1080"));
73172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
7318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
73192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
73212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
73228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
73232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
73252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
73262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockWrite data_writes[] = {
73282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
73292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
73302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Host: www.google.com\r\n"
73312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
73322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
73332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead data_reads[] = {
73352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
73362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
73372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
73382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("Payload"),
73392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
73402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
73412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
73432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                data_writes, arraysize(data_writes));
7344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
73455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
73475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
73495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
73505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
73525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
73535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
73555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
73565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
73582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
73592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReused(load_timing_info,
73602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
73612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_text;
73635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
73645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
73655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Payload", response_text);
73665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
73675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
73695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
73705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
73715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
73725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
73735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
73752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
73762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
7377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
73785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
73805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
73818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
73825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
73845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
73855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5OkRequest[] = {
73865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x05,  // Version
73875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01,  // Command (CONNECT)
73885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00,  // Reserved.
73895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03,  // Address type (DOMAINNAME).
73905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0E,  // Length of domain (14)
73915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Domain string:
73925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
73935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00, 0x50,  // 16-bit port (80)
73945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
73955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5OkResponse[] =
73965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
73975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
73995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
74005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
74015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
74025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
74035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
74045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
74055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
74075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
74085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
74095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
74105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
74115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Payload"),
74125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
74135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
74145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
74165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
74185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
74205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
74225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
74235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
74255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
74265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
74285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
74295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
74312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
74322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
74332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
74342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
74355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_text;
74365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
74375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
74385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Payload", response_text);
74395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
74405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
74425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
74435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
74445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
74455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
74465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
74482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
74492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
7450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
74515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
74535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
74548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
74555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
74575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
74585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const unsigned char kSOCKS5OkRequest[] = {
74595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x05,  // Version
74605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01,  // Command (CONNECT)
74615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x00,  // Reserved.
74625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x03,  // Address type (DOMAINNAME).
74635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0E,  // Length of domain (14)
74645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Domain string:
74655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
74665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x01, 0xBB,  // 16-bit port (443)
74675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
74685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kSOCKS5OkResponse[] =
74705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
74715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
74735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
74745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
74755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              arraysize(kSOCKS5OkRequest)),
74765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
74775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
74785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n")
74795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
74805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
74825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
74835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
74845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n"),
74855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
74865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Payload"),
74875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
74885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
74895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
74915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
7492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
74935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
7495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
74965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
74985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
74995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
75005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
75015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
75035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
75045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
75065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
75075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
75092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
75102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
75112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
75122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
75135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_text;
75145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_text);
75155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
75165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("Payload", response_text);
75175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
75185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
75205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that for connection endpoints the group names are correctly set.
75225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct GroupNameTest {
75245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string proxy_server;
75255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url;
75265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string expected_group_name;
75275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ssl;
75285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
75295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
7531eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    NextProto next_proto,
7532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SpdySessionDependencies* session_deps_) {
7533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
75345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7535ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
75365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
75375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
75385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair("host.with.alternate", 80), 443,
7539116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AlternateProtocolFromNextProto(next_proto), 1);
75405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return session;
75425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
75435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GroupNameTransactionHelper(
75455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& url,
75465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const scoped_refptr<HttpNetworkSession>& session) {
75475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
75485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
75495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL(url);
75505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
75515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
7553868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
75545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
75565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We do not complete this request, the dtor will clean the transaction up.
75585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return trans->Start(&request, callback.callback(), BoundNetLog());
75595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
75605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
75625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
75645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GroupNameTest tests[] = {
75655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
75665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
75675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://www.google.com/direct",
75685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "www.google.com:80",
75695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
75705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
75715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
75725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
75735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://[2001:1418:13:1::25]/direct",
75745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "[2001:1418:13:1::25]:80",
75755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
75765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
75775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SSL Tests
75795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
75805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
75815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://www.google.com/direct_ssl",
75825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/www.google.com:443",
75835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
75845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
75855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
75865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
75875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://[2001:1418:13:1::25]/direct",
75885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/[2001:1418:13:1::25]:443",
75895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
75905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
75915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
75925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "",  // unused
75935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://host.with.alternate/direct",
75945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/host.with.alternate:443",
75955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
75965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
75975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
75985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7599cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
76005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.proxy_service.reset(
76035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProxyService::CreateFixed(tests[i].proxy_server));
76045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(
7605eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SetupSessionForGroupNameTests(GetParam(), &session_deps_));
76065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpNetworkSessionPeer peer(session);
76085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameTransportSocketPool* transport_conn_pool =
76095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameTransportSocketPool(NULL, NULL);
76105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameSSLSocketPool* ssl_conn_pool =
76115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameSSLSocketPool(NULL, NULL);
7612f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7613f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new MockClientSocketPoolManager);
76145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
76155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
7616f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    peer.SetClientSocketPoolManager(
7617f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        mock_pool_manager.PassAs<ClientSocketPoolManager>());
76185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING,
76205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              GroupNameTransactionHelper(tests[i].url, session));
76215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tests[i].ssl)
76225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
76235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl_conn_pool->last_group_name_received());
76245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
76255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
76265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                transport_conn_pool->last_group_name_received());
76275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
76285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
76305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
76325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GroupNameTest tests[] = {
76335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
76345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http_proxy",
76355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://www.google.com/http_proxy_normal",
76365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "www.google.com:80",
76375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
76385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
76395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SSL Tests
76415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
76425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http_proxy",
76435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://www.google.com/http_connect_ssl",
76445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/www.google.com:443",
76455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
76465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
76475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
76495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http_proxy",
76505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://host.with.alternate/direct",
76515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ssl/host.with.alternate:443",
76525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
76535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
76542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
76552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {
76562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "http_proxy",
76572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "ftp://ftp.google.com/http_proxy_normal",
76582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "ftp/ftp.google.com:21",
76592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      false,
76602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    },
76615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
76625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7663cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
76645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.proxy_service.reset(
76675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProxyService::CreateFixed(tests[i].proxy_server));
76685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(
7669eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SetupSessionForGroupNameTests(GetParam(), &session_deps_));
76705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpNetworkSessionPeer peer(session);
76725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostPortPair proxy_host("http_proxy", 80);
76745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
76755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
76765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameSSLSocketPool* ssl_conn_pool =
76775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameSSLSocketPool(NULL, NULL);
76785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7679f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7680f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new MockClientSocketPoolManager);
76815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
76825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7683f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    peer.SetClientSocketPoolManager(
7684f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        mock_pool_manager.PassAs<ClientSocketPoolManager>());
76855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING,
76875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              GroupNameTransactionHelper(tests[i].url, session));
76885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tests[i].ssl)
76895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
76905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl_conn_pool->last_group_name_received());
76915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
76925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
76935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                http_proxy_pool->last_group_name_received());
76945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
76955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
76965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
76977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
76985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GroupNameTest tests[] = {
76995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
77005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4://socks_proxy:1080",
77015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://www.google.com/socks4_direct",
77025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4/www.google.com:80",
77035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
77045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
77055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
77065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks5://socks_proxy:1080",
77075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://www.google.com/socks5_direct",
77085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks5/www.google.com:80",
77095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
77105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
77115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SSL Tests
77135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
77145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4://socks_proxy:1080",
77155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://www.google.com/socks4_ssl",
77165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4/ssl/www.google.com:443",
77175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
77185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
77195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
77205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks5://socks_proxy:1080",
77215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "https://www.google.com/socks5_ssl",
77225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks5/ssl/www.google.com:443",
77235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
77245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
77255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    {
77275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4://socks_proxy:1080",
77285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://host.with.alternate/direct",
77295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "socks4/ssl/host.with.alternate:443",
77305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
77315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    },
77325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
77335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7734cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
77355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
7737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.proxy_service.reset(
77385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProxyService::CreateFixed(tests[i].proxy_server));
77395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(
7740eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        SetupSessionForGroupNameTests(GetParam(), &session_deps_));
77415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpNetworkSessionPeer peer(session);
77435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostPortPair proxy_host("socks_proxy", 1080);
77455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
77465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
77475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptureGroupNameSSLSocketPool* ssl_conn_pool =
77485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new CaptureGroupNameSSLSocketPool(NULL, NULL);
77495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7750f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
7751f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new MockClientSocketPoolManager);
77525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
77535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
7754f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    peer.SetClientSocketPoolManager(
7755f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        mock_pool_manager.PassAs<ClientSocketPoolManager>());
77565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<HttpTransaction> trans(
7758868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
77595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING,
77615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              GroupNameTransactionHelper(tests[i].url, session));
77625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tests[i].ssl)
77635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
77645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                ssl_conn_pool->last_group_name_received());
77655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
77665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(tests[i].expected_group_name,
77675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                socks_conn_pool->last_group_name_received());
77685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
77695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
77705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
77725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
77735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
77745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
77755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
77775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("myproxy:70;foobar:80"));
77785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This simulates failure resolving all hostnames; that means we will fail
77805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connecting to both proxies (myproxy:70 and foobar:80).
7781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
77825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
77845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
77858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
77865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
77885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
77905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
77915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
77935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
77945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
77955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Base test to make sure that when the load flags for a request specify to
77975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bypass the cache, the DNS cache is not used.
77987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
7799c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int load_flags) {
78005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue a request, asking to bypass the cache(s).
78015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
78025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
78035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = load_flags;
78045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
78055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Select a host resolver that does caching.
7807c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver.reset(new MockCachingHostResolver);
78085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
78108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
78118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
78125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Warm up the host cache so it has an entry for "www.google.com".
78145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList addrlist;
78155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
7816c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int rv = session_deps_.host_resolver->Resolve(
78173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
78183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      DEFAULT_PRIORITY,
78193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      &addrlist,
78203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      callback.callback(),
78213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      NULL,
78223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      BoundNetLog());
78235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
78245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
78255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
78265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that it was added to host cache, by doing a subsequent async lookup
78285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and confirming it completes synchronously.
7829c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  rv = session_deps_.host_resolver->Resolve(
78303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
78313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      DEFAULT_PRIORITY,
78323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      &addrlist,
78333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      callback.callback(),
78343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      NULL,
78353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      BoundNetLog());
78365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, rv);
78375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Inject a failure the next time that "www.google.com" is resolved. This way
78395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we can tell if the next lookup hit the cache, or the "network".
78405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (cache --> success, "network" --> failure).
7841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
78425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
78445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // first read -- this won't be reached as the host resolution will fail first.
78455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
78465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
78485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Run the request.
78505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
78515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING, rv);
78525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
78535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we bypassed the cache, we would have gotten a failure while resolving
78555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "www.google.com".
78565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
78575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
78585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There are multiple load flags that should trigger the host cache bypass.
78605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test each in isolation:
78617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
78625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
78635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
78645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
78665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
78675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
78685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
78705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
78715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
78725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure we can handle an error when writing the request.
78747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
78755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
78765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
78775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
78785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
78795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite write_failure[] = {
78815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, ERR_CONNECTION_RESET),
78825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
78835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(NULL, 0,
78845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                write_failure, arraysize(write_failure));
7885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
78868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
78875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
78895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
78918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
78925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
78945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
78955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
78965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
78975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
78985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
78995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that a connection closed after the start of the headers finishes ok.
79017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
79025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
79035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
79045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.foo.com/");
79055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
79065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
79085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1."),
79095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
79105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
79115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
7913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
79148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
79155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
79175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
79198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
79205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
79225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
79235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
79255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
79265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
79285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
79295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7930868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
79315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
79325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
79345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
79355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
79365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("", response_data);
79375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
79385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that a dropped connection while draining the body for auth
79405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// restart does the right thing.
79417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
79425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
79435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
79445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
79455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
79465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
79485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
79495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
79505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
79515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
79525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
79545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"),
79555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
79565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
79575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 14\r\n\r\n"),
79585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Unauth"),
79595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_CONNECTION_RESET),
79605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
79615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
79635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
7964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
79655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), this is the request we should
79675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be issuing -- the final header line contains the credentials.
79685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
79695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
79705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
79715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
79725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
79735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
79745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Lastly, the server responds with the actual content.
79765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
79775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
79785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
79795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
79805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
79815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
79825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
79845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
7985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
79868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
79875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
79895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
7991868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
79925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
79945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
79955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
79975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
79985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
79995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
80005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
80015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
80025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
80045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
80065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback2.callback());
80075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
80085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
80105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
80115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
80135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
80145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
80155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
80165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
80175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test HTTPS connections going through a proxy that sends extra data.
80197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
8020c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
80215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
80235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
80245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
80255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
80265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead proxy_reads[] = {
80285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
80295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK)
80305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
80315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
80335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
80345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8035c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
8036c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
80375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
80395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8040c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->ResetNextMockIndexes();
80415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
80435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
80448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
80455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
80475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
80485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
80505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
80515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
80525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
80545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
80555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
80565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
80575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
80585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
80605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
80618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
80625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
80645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
80655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
80665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
80675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8069c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
80705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
80725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
80745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
80755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
80775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
80795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
80805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8081868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
80825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
80835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
80855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
80865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
80875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
80885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
80902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath temp_file_path;
8091a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
80922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const uint64 kFakeSize = 100000;  // file is actually blank
80932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UploadFileElementReader::ScopedOverridingContentLengthForTests
80942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      overriding_content_length(kFakeSize);
80952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
80962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
80972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(
80987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      new UploadFileElementReader(base::MessageLoopProxy::current().get(),
80997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  temp_file_path,
81007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  0,
81017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  kuint64max,
81027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  base::Time()));
810368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
81042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
81055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
81065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
81075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/upload");
81082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.upload_data_stream = &upload_data_stream;
81095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
81105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
81125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
81138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
81145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
81165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.0 200 OK\r\n\r\n"),
81175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
81185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
81195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
81205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
81225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
81245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
81265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
81275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
81295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
81305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
81325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
81335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(response->headers.get() != NULL);
81355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
81365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
81385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = ReadTransaction(trans.get(), &response_data);
81395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
81405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
81415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::DeleteFile(temp_file_path, false);
81435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
81445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
81462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath temp_file;
8147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
81482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string temp_file_content("Unreadable file.");
8149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
81502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   temp_file_content.length()));
81512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
81522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
81532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
81542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element_readers.push_back(
81557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      new UploadFileElementReader(base::MessageLoopProxy::current().get(),
81567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  temp_file,
81577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  0,
81587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  kuint64max,
81597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                  base::Time()));
816068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
81612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
81625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
81635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "POST";
81645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/upload");
81652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  request.upload_data_stream = &upload_data_stream;
81665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
81675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If we try to upload an unreadable file, the transaction should fail.
81698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
81705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
81718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
81725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  StaticSocketDataProvider data(NULL, 0, NULL, 0);
8174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
81755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
81775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
81795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
81805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
8182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(ERR_ACCESS_DENIED, rv);
81835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
8185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(response);
81865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::DeleteFile(temp_file, false);
81885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
81895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
81914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  class FakeUploadElementReader : public UploadElementReader {
81924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   public:
81934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    FakeUploadElementReader() {}
81944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual ~FakeUploadElementReader() {}
81954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
81964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const CompletionCallback& callback() const { return callback_; }
81974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
81984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // UploadElementReader overrides:
81994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual int Init(const CompletionCallback& callback) OVERRIDE {
82004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      callback_ = callback;
82014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return ERR_IO_PENDING;
82024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
82034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual uint64 GetContentLength() const OVERRIDE { return 0; }
82044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual uint64 BytesRemaining() const OVERRIDE { return 0; }
82054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    virtual int Read(IOBuffer* buf,
82064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                     int buf_length,
82074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                     const CompletionCallback& callback) OVERRIDE {
82084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return ERR_FAILED;
82094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
82104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)   private:
82124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    CompletionCallback callback_;
82134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  };
82144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
82164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ScopedVector<UploadElementReader> element_readers;
82174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  element_readers.push_back(fake_reader);
82184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
82194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  HttpRequestInfo request;
82214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.method = "POST";
82224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.url = GURL("http://www.google.com/upload");
82234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.upload_data_stream = &upload_data_stream;
82244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  request.load_flags = 0;
82254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
82274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
82288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
82294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  StaticSocketDataProvider data;
82314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
82324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  TestCompletionCallback callback;
82344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
82354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
82364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
82374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Transaction is pending on request body initialization.
82394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ASSERT_FALSE(fake_reader->callback().is_null());
82404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Return Init()'s result after the transaction gets destroyed.
82424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  trans.reset();
82434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  fake_reader->callback().Run(OK);  // Should not crash.
82444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
82454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
82465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that changes to Auth realms are treated like auth rejections.
82477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
82485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
82505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
82515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
82525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
82535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First transaction will request a resource and receive a Basic challenge
82555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // with realm="first_realm".
82565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
82575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
82585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
82595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
82605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
82615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
82635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"
82645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
82655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"),
82665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After calling trans->RestartWithAuth(), provide an Authentication header
82695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for first_realm. The server will reject and provide a challenge with
82705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // second_realm.
82715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes2[] = {
82725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
82735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
82745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
82755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zmlyc3Q6YmF6\r\n"
82765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
82775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads2[] = {
82795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"
82805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
82815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"),
82825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This again fails, and goes back to first_realm. Make sure that the
82855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // entry is removed from cache.
82865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes3[] = {
82875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
82885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
82895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
82905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
82915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
82925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads3[] = {
82945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 401 Unauthorized\r\n"
82955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
82965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"),
82975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
82985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try one last time (with the correct password) and get the resource.
83005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes4[] = {
83015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
83025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
83035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n"
83045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Authorization: Basic Zmlyc3Q6YmFy\r\n"
83055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
83065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
83075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads4[] = {
83085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"
83095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Type: text/html; charset=iso-8859-1\r\n"
83105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Content-Length: 5\r\n"
83115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"
83125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "hello"),
83135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
83145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
83165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
83175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
83185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes2, arraysize(data_writes2));
83195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
83205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes3, arraysize(data_writes3));
83215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
83225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes4, arraysize(data_writes4));
8323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
8324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
8325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
8326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data4);
83275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
83295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
83315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
83328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
83335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the first request with Authorize headers. There should be a
83355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // password prompt for first_realm waiting to be filled in after the
83365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction completes.
83375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
83385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
83395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
83405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
83415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
83425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
83435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const AuthChallengeInfo* challenge = response->auth_challenge.get();
83445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(challenge == NULL);
83455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(challenge->is_proxy);
83465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
83475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("first_realm", challenge->realm);
83485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", challenge->scheme);
83495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the second request with an incorrect password. There should be a
83515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // password prompt for second_realm waiting to be filled in after the
83525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // transaction completes.
83535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
83545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
83555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFirst, kBaz), callback2.callback());
83565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
83575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback2.WaitForResult();
83585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
83595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
83605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
83615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  challenge = response->auth_challenge.get();
83625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(challenge == NULL);
83635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(challenge->is_proxy);
83645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
83655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("second_realm", challenge->realm);
83665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", challenge->scheme);
83675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the third request with another incorrect password. There should be
83695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a password prompt for first_realm waiting to be filled in. If the password
83705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // prompt is not present, it indicates that the HttpAuthCacheEntry for
83715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // first_realm was not correctly removed.
83725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
83735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
83745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kSecond, kFou), callback3.callback());
83755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
83765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback3.WaitForResult();
83775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
83785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
83795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
83805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  challenge = response->auth_challenge.get();
83815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(challenge == NULL);
83825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(challenge->is_proxy);
83835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
83845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("first_realm", challenge->realm);
83855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("basic", challenge->scheme);
83865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Issue the fourth request with the correct password and username.
83885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback4;
83895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(
83905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFirst, kBar), callback4.callback());
83915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
83925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback4.WaitForResult();
83935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
83945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
83955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
83965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
83975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
83985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
83997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
8400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
8401cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
84025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
8404eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
8405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
84065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
84075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
84095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
84105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
84115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
84125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
84145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
84155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
84165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
84175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
84195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
84215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
84235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
84252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8426868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
84275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
84295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
84305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair http_host_port_pair("www.google.com", 80);
8432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  HttpServerProperties& http_server_properties =
84335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *session->http_server_properties();
84345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
84355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_server_properties.HasAlternateProtocol(http_host_port_pair));
84365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
84385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
84405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8441868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
84425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
84435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
84445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_npn_negotiated);
84455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
84475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
84485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
84495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
8451116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const AlternateProtocolInfo alternate =
84525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_server_properties.GetAlternateProtocol(http_host_port_pair);
8453116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AlternateProtocolInfo expected_alternate(
8454116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      443, AlternateProtocolFromNextProto(GetParam()), 1);
84555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(expected_alternate.Equals(alternate));
84565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
84575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
84595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       MarkBrokenAlternateProtocolAndFallback) {
8460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
84615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
84635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
84645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
84655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
84665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
84685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
84695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
84715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
84735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
84745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
84755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
84765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
84775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
84785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
84805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
84825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8483ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
84845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
84855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Port must be < 1024, or the header will be ignored (since initial port was
84865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // port 80 (another restricted port).
84875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
84885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(request.url),
84895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      666 /* port is ignored by MockConnect anyway */,
8490116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AlternateProtocolFromNextProto(GetParam()), 1);
84915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8493868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
84945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
84955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
84975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
84985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
84995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
85015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8502868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
85035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
85045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
85065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
85075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
85085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
85105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(request.url)));
8511116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const AlternateProtocolInfo alternate =
85125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      http_server_properties->GetAlternateProtocol(
85135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          HostPortPair::FromURL(request.url));
85145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
85155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
85165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
85185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolPortRestrictedBlocked) {
85195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
85205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
85215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a restricted port (port < 1024).  Ensure that we can redirect in all
85225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other cases.
8523cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
85245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo restricted_port_request;
85265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.method = "GET";
85275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.url = GURL("http://www.google.com:1023/");
85285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.load_flags = 0;
85295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
85315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
85325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
85345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
85365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
85375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
85385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
85395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
85405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
85415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
85435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
85455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8546ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
85475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
85485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kUnrestrictedAlternatePort = 1024;
85495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
85505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(restricted_port_request.url),
85515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUnrestrictedAlternatePort,
8552116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AlternateProtocolFromNextProto(GetParam()), 1);
85535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8555868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
85565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
85575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(
85592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &restricted_port_request,
85602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback.callback(), BoundNetLog());
85615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
85625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invalid change to unrestricted port should fail.
85635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
85642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
85655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
85672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       AlternateProtocolPortRestrictedPermitted) {
85682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ensure that we're allowed to redirect traffic via an alternate
85692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
85702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // on a restricted port (port < 1024) if we set
85712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // enable_user_alternate_protocol_ports.
85722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8573cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
8574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.enable_user_alternate_protocol_ports = true;
85752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
85762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpRequestInfo restricted_port_request;
85772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  restricted_port_request.method = "GET";
85782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  restricted_port_request.url = GURL("http://www.google.com:1023/");
85792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  restricted_port_request.load_flags = 0;
85802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
85812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
85822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider first_data;
85832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  first_data.set_connect_data(mock_connect);
8584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
85852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
85862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRead data_reads[] = {
85872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
85882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead("hello world"),
85892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockRead(ASYNC, OK),
85902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
85912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StaticSocketDataProvider second_data(
85922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
85942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
85962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8597ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
85982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      session->http_server_properties();
85992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const int kUnrestrictedAlternatePort = 1024;
86002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  http_server_properties->SetAlternateProtocol(
86012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HostPortPair::FromURL(restricted_port_request.url),
86022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kUnrestrictedAlternatePort,
8603116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AlternateProtocolFromNextProto(GetParam()), 1);
86042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
86052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
86072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestCompletionCallback callback;
86082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
86092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, trans->Start(
86102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &restricted_port_request,
86112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback.callback(), BoundNetLog()));
86122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Change to unrestricted port should succeed.
86132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
86145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
86155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
86175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolPortRestrictedAllowed) {
86185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
86195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
86205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a restricted port (port < 1024).  Ensure that we can redirect in all
86215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other cases.
8622cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
86235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo restricted_port_request;
86255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.method = "GET";
86265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.url = GURL("http://www.google.com:1023/");
86275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  restricted_port_request.load_flags = 0;
86285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
86305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
86315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
86335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
86355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
86365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
86375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
86385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
86395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
86405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
86425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
86445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8645ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
86465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
86475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kRestrictedAlternatePort = 80;
86485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
86495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(restricted_port_request.url),
86505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kRestrictedAlternatePort,
8651116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AlternateProtocolFromNextProto(GetParam()), 1);
86525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8654868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
86555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
86565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(
86582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &restricted_port_request,
86592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback.callback(), BoundNetLog());
86605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
86615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Valid change to restricted port should pass.
86625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
86635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
86645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
86665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolPortUnrestrictedAllowed1) {
86675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
86685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
86695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a restricted port (port < 1024).  Ensure that we can redirect in all
86705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other cases.
8671cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
86725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo unrestricted_port_request;
86745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.method = "GET";
86755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.url = GURL("http://www.google.com:1024/");
86765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.load_flags = 0;
86775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
86795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
86805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
86825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
86845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
86855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
86865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
86875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
86885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
86895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
86915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
86935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8694ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
86955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
86965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kRestrictedAlternatePort = 80;
86975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
86985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(unrestricted_port_request.url),
86995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kRestrictedAlternatePort,
8700116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AlternateProtocolFromNextProto(GetParam()), 1);
87015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8703868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
87045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
87055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(
87075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &unrestricted_port_request, callback.callback(), BoundNetLog());
87085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
87095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Valid change to restricted port should pass.
87105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
87115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
87125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
87145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       AlternateProtocolPortUnrestrictedAllowed2) {
87155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
87165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unrestricted (port >= 1024) when the original traffic was
87175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on a restricted port (port < 1024).  Ensure that we can redirect in all
87185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // other cases.
8719cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
87205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo unrestricted_port_request;
87225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.method = "GET";
87235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.url = GURL("http://www.google.com:1024/");
87245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unrestricted_port_request.load_flags = 0;
87255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
87275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_data;
87285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  first_data.set_connect_data(mock_connect);
8729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_data);
87305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
87325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
87335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
87345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
87355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
87365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider second_data(
87375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8738c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&second_data);
87395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
87415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8742ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
87435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
87445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kUnrestrictedAlternatePort = 1024;
87455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
87465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(unrestricted_port_request.url),
87475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUnrestrictedAlternatePort,
8748116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AlternateProtocolFromNextProto(GetParam()), 1);
87495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8751868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
87525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
87535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(
87555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &unrestricted_port_request, callback.callback(), BoundNetLog());
87565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
87575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Valid change to an unrestricted port should pass.
87585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
87595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
87605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8761cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
87625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that we're not allowed to redirect traffic via an alternate
87635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // protocol to an unsafe port, and that we resume the second
87645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
8765cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
87665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
87685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
87695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
87705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
87715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The alternate protocol request will error out before we attempt to connect,
87735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so only the standard HTTP request will try to connect.
87745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
87755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
87765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
87775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
87785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
87795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(
87805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
87825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
87845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8785ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<HttpServerProperties> http_server_properties =
87865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      session->http_server_properties();
87875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kUnsafePort = 7;
87885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_server_properties->SetAlternateProtocol(
87895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostPortPair::FromURL(request.url),
87905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kUnsafePort,
8791116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      AlternateProtocolFromNextProto(GetParam()), 1);
87925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8794868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
87955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
87965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
87975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
87985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
87995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The HTTP request should succeed.
88005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
88015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disable alternate protocol before the asserts.
8803cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // HttpStreamFactory::set_use_alternate_protocols(false);
88045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
88065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8807868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
88085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
88095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
88115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
88125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
88135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
88145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
8816cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
8817cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
88185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
88205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
88215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
88225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
88235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8824eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
8825eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
8826eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
88275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
88285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8829eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
88305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
88315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
88325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK)
88335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
88345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
88365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
8837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
88385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
88407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
8841c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
88425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
884390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
884490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
88455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
88465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
88487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
88495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
88505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
88515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data),
88525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
88535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
88545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
88565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
88575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
88585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
8859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
88605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
88625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_non_alternate_protocol_socket(
88635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
88645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_non_alternate_protocol_socket.set_connect_data(
88655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      never_finishing_connect);
8866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(
88675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &hanging_non_alternate_protocol_socket);
88685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
88705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
88722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
8873868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
88745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
88765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
88775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
88785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
88805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8881868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
88825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
88835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
88855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
88865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
88875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8888868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
88895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
88915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
88925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
88935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
88945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
88955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8896868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
88975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
88985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
88995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
89005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
89025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
89035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
89045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
8906cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
8907cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
89085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
89105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
89115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
89125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
89135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8914eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
8915eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
8916eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
89175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
89185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
8919eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
89205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
89215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
89225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
89235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
89245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
89265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
89275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
8928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
89295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
89315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_socket(
89325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
89335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_socket.set_connect_data(never_finishing_connect);
89345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket 2 and 3 are the hanging Alternate-Protocol and
89355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // non-Alternate-Protocol jobs from the 2nd transaction.
8936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
8937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
89385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
89407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
8941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
89425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
894390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(
894490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
894590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
894690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
89475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
89485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req1),
89495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2),
89505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
89517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
89527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
89537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
89547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
89555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
89565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp1),
89575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data1),
89585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2),
89595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data2),
89605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
89615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
89625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
89645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      2,  // wait for writes to finish before reading.
89655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
89665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
89675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket 4 is the successful Alternate-Protocol for transaction 3.
8968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
89695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
8971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
89725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
89745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
8975868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
89765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
89785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
89795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
89805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans1.GetResponseInfo();
89825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
8983868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
89845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
89855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
89875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
89885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
89895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
8991868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
89925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
89935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
89945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback3;
8996868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
89975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
89985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
89995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
90015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback3.WaitForResult());
90025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans2.GetResponseInfo();
90045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9005868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
90065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
90075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
90085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
90095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
90105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
90115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans3.GetResponseInfo();
90135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9014868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
90155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
90165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
90175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
90185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
90195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
90205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
90215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
9023cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
9024cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
90255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
90275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
90285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
90295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
90305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9031eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
9032eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
9033eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
90345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
90355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
9036eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
90375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
90385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
90395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
90405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
90415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
90435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
9044c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
90455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
90477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
9048c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
90495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
90515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_alternate_protocol_socket(
90525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
90535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_alternate_protocol_socket.set_connect_data(
90545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      never_finishing_connect);
9055c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(
90565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &hanging_alternate_protocol_socket);
90575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2nd request is just a copy of the first one, over HTTP again.
9059c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
90605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
90625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9063c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
90642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9065868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
90665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
90685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
90695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
90705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
90725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9073868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
90745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
90755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
90775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
90785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
90795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9080868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
90815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
90835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
90845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
90855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
90875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9088868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
90895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
90905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
90915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_npn_negotiated);
90925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
90945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
90955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
90965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CapturingProxyResolver : public ProxyResolver {
90985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
90995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
91005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~CapturingProxyResolver() {}
91015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetProxyForURL(const GURL& url,
91035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             ProxyInfo* results,
91045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const CompletionCallback& callback,
91055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             RequestHandle* request,
91062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const BoundNetLog& net_log) OVERRIDE {
91075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
91085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             HostPortPair("myproxy", 80));
91095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    results->UseProxyServer(proxy_server);
91105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resolved_.push_back(url);
91115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
91125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
91135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void CancelRequest(RequestHandle request) OVERRIDE {
91155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
91165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
91175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
91195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
91205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return LOAD_STATE_IDLE;
91215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
91225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void CancelSetPacScript() OVERRIDE {
91245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
91255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
91265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
91282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const CompletionCallback& /*callback*/) OVERRIDE {
91295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return OK;
91305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
91315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::vector<GURL>& resolved() const { return resolved_; }
91335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
91355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<GURL> resolved_;
91365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
91385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
91395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
91415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       UseAlternateProtocolForTunneledNpnSpdy) {
9142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
9143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
91445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig proxy_config;
91465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxy_config.set_auto_detect(true);
91475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxy_config.set_pac_url(GURL("http://fooproxyurl"));
91485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingProxyResolver* capturing_proxy_resolver =
91505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new CapturingProxyResolver();
9151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(new ProxyService(
91525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
91535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL));
91542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
9155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
91565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
91585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
91595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
91605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
91615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
9163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
9164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
91655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
91665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
9167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
91685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
91695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
91705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
91715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
91725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
91745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
9175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
91765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
91787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
9179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
91805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
918190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
918290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
91835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
91845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
91855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
91865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),  // 0
918790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    CreateMockWrite(*req),                              // 3
91885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
91895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
91915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
91927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
91937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
91945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
91955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1),  // 1
91965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp.get(), 4),  // 2, 4
91975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data.get(), 4),  // 5
91985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0, 4),  // 6
91995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
92005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
92025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
92035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
9204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
92055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
92075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_non_alternate_protocol_socket(
92085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
92095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_non_alternate_protocol_socket.set_connect_data(
92105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      never_finishing_connect);
9211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(
92125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &hanging_non_alternate_protocol_socket);
92135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
92155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
92172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
92195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
92215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
92225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
92235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
92255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
92275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
92285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
92295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_npn_negotiated);
92305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
92325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
92335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
92345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
92365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
92385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
92395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
92405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
92425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
92445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
92455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
92465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
92475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
92495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
92505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
92515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("http://www.google.com/",
92525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            capturing_proxy_resolver->resolved()[0].spec());
92535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("https://www.google.com/",
92545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            capturing_proxy_resolver->resolved()[1].spec());
92555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
92572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
92582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
92592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
92605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
92615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
92635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
9264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
9265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
92665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
92685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
92695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
92705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
92715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
9273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
9274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
92755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
92765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
9277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
92785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
92795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK),
92805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
92815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider first_transaction(
92835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads, arraysize(data_reads), NULL, 0);
9284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
92855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
92877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
9288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
92895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
929090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
929190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
92925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
92935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
92957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
92965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
92975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
92985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data),
92995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
93005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
93015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
93035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
93045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
93055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
9306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
93075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
93095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
93115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
93145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
93165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
93175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
93185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
93205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9321868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
93225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
93235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
93255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
93265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
93275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up an initial SpdySession in the pool to reuse.
93295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair host_port_pair("www.google.com", 443);
933090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
9331e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                     PRIVACY_MODE_DISABLED);
9332ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<SpdySession> spdy_session =
93337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      CreateSecureSpdySession(session, key, BoundNetLog());
93345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
93365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
93385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
93395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
93405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
93425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
9343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
93445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
93455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
93465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
93475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
93495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
93505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
93515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GenerateAuthToken is a mighty big test.
93535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It tests all permutation of GenerateAuthToken behavior:
93545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - Synchronous and Asynchronous completion.
93555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - OK or error on completion.
93565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - Direct connection, non-authenticating proxy, and authenticating proxy.
93575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - HTTP or HTTPS backend (to include proxy tunneling).
93585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   - Non-authenticating and authenticating backend.
93595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
93605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In all, there are 44 reasonable permuations (for example, if there are
93615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// problems generating an auth token for an authenticating proxy, we don't
93625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// need to test all permutations of the backend server).
93635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
93645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The test proceeds by going over each of the configuration cases, and
93655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// potentially running up to three rounds in each of the tests. The TestConfig
93665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// specifies both the configuration for the test as well as the expectations
93675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for the results.
93687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
93695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kServer[] = "http://www.example.com";
93705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kSecureServer[] = "https://www.example.com";
93715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kProxy[] = "myproxy:70";
93725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
93735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum AuthTiming {
93755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AUTH_NONE,
93765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AUTH_SYNC,
93775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AUTH_ASYNC,
93785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
93795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGet(
93815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET / HTTP/1.1\r\n"
93825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
93835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Connection: keep-alive\r\n\r\n");
93845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetProxy(
93855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET http://www.example.com/ HTTP/1.1\r\n"
93865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
93875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n\r\n");
93885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetAuth(
93895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET / HTTP/1.1\r\n"
93905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
93915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Connection: keep-alive\r\n"
93925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Authorization: auth_token\r\n\r\n");
93935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetProxyAuth(
93945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET http://www.example.com/ HTTP/1.1\r\n"
93955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
93965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n"
93975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Authorization: auth_token\r\n\r\n");
93985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetAuthThroughProxy(
93995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET http://www.example.com/ HTTP/1.1\r\n"
94005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
94015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n"
94025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Authorization: auth_token\r\n\r\n");
94035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetAuthWithProxyAuth(
94045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET http://www.example.com/ HTTP/1.1\r\n"
94055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
94065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n"
94075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Authorization: auth_token\r\n"
94085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Authorization: auth_token\r\n\r\n");
94095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kConnect(
94105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "CONNECT www.example.com:443 HTTP/1.1\r\n"
94115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
94125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n\r\n");
94135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kConnectProxyAuth(
94145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "CONNECT www.example.com:443 HTTP/1.1\r\n"
94155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
94165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: keep-alive\r\n"
94175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Authorization: auth_token\r\n\r\n");
94185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kSuccess(
94205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\r\n"
94215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
94225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 3\r\n\r\n"
94235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Yes");
94245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kFailure(
94255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Should not be called.");
94265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kServerChallenge(
94275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 401 Unauthorized\r\n"
94285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "WWW-Authenticate: Mock realm=server\r\n"
94295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
94305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 14\r\n\r\n"
94315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Unauthorized\r\n");
94325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kProxyChallenge(
94335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 407 Unauthorized\r\n"
94345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Authenticate: Mock realm=proxy\r\n"
94355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Proxy-Connection: close\r\n"
94365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
94375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 14\r\n\r\n"
94385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Unauthorized\r\n");
94395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kProxyConnected(
94405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 Connection Established\r\n\r\n");
94415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
94435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // no constructors, but the C++ compiler on Windows warns about
94445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // unspecified data in compound literals. So, moved to using constructors,
94455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and TestRound's created with the default constructor should not be used.
94465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct TestRound {
94475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRound()
94485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : expected_rv(ERR_UNEXPECTED),
94495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_write(NULL),
94505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_read(NULL) {
94515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
94525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRound(const MockWrite& write_arg, const MockRead& read_arg,
94535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              int expected_rv_arg)
94545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : write(write_arg),
94555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          read(read_arg),
94565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          expected_rv(expected_rv_arg),
94575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_write(NULL),
94585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_read(NULL) {
94595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
94605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRound(const MockWrite& write_arg, const MockRead& read_arg,
94615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              int expected_rv_arg, const MockWrite* extra_write_arg,
94625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              const MockRead* extra_read_arg)
94635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : write(write_arg),
94645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          read(read_arg),
94655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          expected_rv(expected_rv_arg),
94665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_write(extra_write_arg),
94675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extra_read(extra_read_arg) {
94685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
94695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite write;
94705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead read;
94715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int expected_rv;
94725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockWrite* extra_write;
94735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MockRead* extra_read;
94745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
94755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kNoSSL = 500;
94775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct TestConfig {
94795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* proxy_url;
94805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AuthTiming proxy_auth_timing;
94815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int proxy_auth_rv;
94825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* server_url;
94835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AuthTiming server_auth_timing;
94845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int server_auth_rv;
94855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int num_auth_rounds;
94865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int first_ssl_round;
94875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestRound rounds[3];
94885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } test_configs[] = {
94895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTP server with a direct connection.
94905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
94915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kSuccess, OK)}},
94925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTP server with a direct connection.
94935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
94945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
94955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
94965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
94975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
94985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
94995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
95005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
95015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
95025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
95035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
95045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
95055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTP server through a non-authenticating proxy.
95065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
95075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kSuccess, OK)}},
95085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTP server through a non-authenticating proxy.
95095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
95105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kServerChallenge, OK),
95115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
95125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
95135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kServerChallenge, OK),
95145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
95155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
95165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kServerChallenge, OK),
95175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
95185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
95195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kServerChallenge, OK),
95205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
95215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTP server through an authenticating proxy.
95225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
95235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kSuccess, OK)}},
95255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
95265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
95285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
95295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kSuccess, OK)}},
95315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
95325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
95345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTP server through an authenticating proxy.
95355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
95365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
95395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
95405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
95435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
95445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
95475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
95485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
95515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
95525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
95555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
95565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
95595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
95605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
95635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
95645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGetProxy, kProxyChallenge, OK),
95655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetProxyAuth, kServerChallenge, OK),
95665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
95675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTPS server with a direct connection.
95685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
95695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kSuccess, OK)}},
95705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTPS server with a direct connection.
95715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
95725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
95735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
95745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
95755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
95765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
95775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
95785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
95795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
95805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
95815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kGet, kServerChallenge, OK),
95825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
95835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-authenticating HTTPS server with a non-authenticating proxy.
95845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
95855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
95865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTPS server through a non-authenticating proxy.
95875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
95885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
95895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
95905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
95915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
95925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
95935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
95945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
95955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
95965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
95975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
95985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
95995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Non-Authenticating HTTPS server through an authenticating proxy.
96005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
96015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
96035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
96045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
96065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
96075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
96095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
96105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
96125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Authenticating HTTPS server through an authenticating proxy.
96135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
96145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
96165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
96175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
96185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
96195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
96215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
96225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
96235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
96245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
96265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
96275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
96285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
96295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
96315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
96325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
96335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
96345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
96365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
96375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
96385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
96395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
96415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
96425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
96435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
96445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
96465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
96475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kSuccess, OK)}},
96485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
96495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { TestRound(kConnect, kProxyChallenge, OK),
96505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kConnectProxyAuth, kProxyConnected, OK,
96515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  &kGet, &kServerChallenge),
96525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestRound(kGetAuth, kFailure, kAuthErr)}},
96535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
96545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
96565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpAuthHandlerMock::Factory* auth_factory(
96575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new HttpAuthHandlerMock::Factory());
9658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.http_auth_handler_factory.reset(auth_factory);
96595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const TestConfig& test_config = test_configs[i];
96605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Set up authentication handlers as necessary.
96625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_config.proxy_auth_timing != AUTH_NONE) {
96635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (int n = 0; n < 2; n++) {
96645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
96655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::string auth_challenge = "Mock realm=proxy";
96665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL origin(test_config.proxy_url);
9667a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9668a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                             auth_challenge.end());
96695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
96705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        origin, BoundNetLog());
96715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        auth_handler->SetGenerateExpectation(
96725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            test_config.proxy_auth_timing == AUTH_ASYNC,
96735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            test_config.proxy_auth_rv);
96745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
96755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
96765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
96775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_config.server_auth_timing != AUTH_NONE) {
96785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
96795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string auth_challenge = "Mock realm=server";
96805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL origin(test_config.server_url);
9681a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9682a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                           auth_challenge.end());
96835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
96845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      origin, BoundNetLog());
96855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      auth_handler->SetGenerateExpectation(
96865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          test_config.server_auth_timing == AUTH_ASYNC,
96875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          test_config.server_auth_rv);
96885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
96895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
96905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (test_config.proxy_url) {
9691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.proxy_service.reset(
96925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ProxyService::CreateFixed(test_config.proxy_url));
96935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
9694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.proxy_service.reset(ProxyService::CreateDirect());
96955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
96965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpRequestInfo request;
96985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.method = "GET";
96995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.url = GURL(test_config.server_url);
97005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request.load_flags = 0;
97015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
97038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
97045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int round = 0; round < test_config.num_auth_rounds; ++round) {
97065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const TestRound& read_write_round = test_config.rounds[round];
97075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Set up expected reads and writes.
97095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockRead reads[2];
97105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reads[0] = read_write_round.read;
97115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t length_reads = 1;
97125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (read_write_round.extra_read) {
97135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reads[1] = *read_write_round.extra_read;
97145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        length_reads = 2;
97155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
97165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      MockWrite writes[2];
97185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writes[0] = read_write_round.write;
97195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      size_t length_writes = 1;
97205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (read_write_round.extra_write) {
97215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        writes[1] = *read_write_round.extra_write;
97225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        length_writes = 2;
97235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
97245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      StaticSocketDataProvider data_provider(
97255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          reads, length_reads, writes, length_writes);
9726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
97275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Add an SSL sequence if necessary.
97295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
97305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (round >= test_config.first_ssl_round)
9731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        session_deps_.socket_factory->AddSSLSocketDataProvider(
97325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &ssl_socket_data_provider);
97335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Start or restart the transaction.
97355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TestCompletionCallback callback;
97365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int rv;
97375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (round == 0) {
97385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = trans.Start(&request, callback.callback(), BoundNetLog());
97395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
97405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = trans.RestartWithAuth(
97415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            AuthCredentials(kFoo, kBar), callback.callback());
97425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
97435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (rv == ERR_IO_PENDING)
97445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rv = callback.WaitForResult();
97455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Compare results with expected data.
97475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(read_write_round.expected_rv, rv);
97485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const HttpResponseInfo* response = trans.GetResponseInfo();
97495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (read_write_round.expected_rv == OK) {
97505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ASSERT_TRUE(response != NULL);
97515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
97525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(response == NULL);
97535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_EQ(round + 1, test_config.num_auth_rounds);
97545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
97555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
97565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (round + 1 < test_config.num_auth_rounds) {
97575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_FALSE(response->auth_challenge.get() == NULL);
97585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
97595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EXPECT_TRUE(response->auth_challenge.get() == NULL);
97605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
97615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
97625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
97635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
97645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
97665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do multi-round authentication and make sure it works correctly.
97675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerMock::Factory* auth_factory(
97685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new HttpAuthHandlerMock::Factory());
9769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.http_auth_handler_factory.reset(auth_factory);
9770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateDirect());
9771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
9772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->set_synchronous_mode(true);
97735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
97755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->set_connection_based(true);
97765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string auth_challenge = "Mock realm=server";
97775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL origin("http://www.example.com");
9778a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
9779a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                       auth_challenge.end());
97805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
97815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  origin, BoundNetLog());
97825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
97835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = OK;
97855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = NULL;
97865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
97875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
97885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = origin;
97895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
97905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
97925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
97935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use a TCP Socket Pool with only one connection per group. This is used
97945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to validate that the TCP socket is not released to the pool between
97955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // each round of multi-round authentication.
97965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpNetworkSessionPeer session_peer(session);
97975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
97985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
97995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      50,  // Max sockets for pool
98005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,   // Max sockets per group
98015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &transport_pool_histograms,
9802c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.host_resolver.get(),
9803c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.socket_factory.get(),
9804c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      session_deps_.net_log);
9805f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
9806f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      new MockClientSocketPoolManager);
98075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mock_pool_manager->SetTransportSocketPool(transport_pool);
9808f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  session_peer.SetClientSocketPoolManager(
9809f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      mock_pool_manager.PassAs<ClientSocketPoolManager>());
98105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9812868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
98135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
98145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGet(
98165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET / HTTP/1.1\r\n"
98175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
98185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Connection: keep-alive\r\n\r\n");
98195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockWrite kGetAuth(
98205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "GET / HTTP/1.1\r\n"
98215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Host: www.example.com\r\n"
98225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Connection: keep-alive\r\n"
98235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Authorization: auth_token\r\n\r\n");
98245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kServerChallenge(
98265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 401 Unauthorized\r\n"
98275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "WWW-Authenticate: Mock realm=server\r\n"
98285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
98295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 14\r\n\r\n"
98305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Unauthorized\r\n");
98315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const MockRead kSuccess(
98325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "HTTP/1.1 200 OK\r\n"
98335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Type: text/html; charset=iso-8859-1\r\n"
98345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Content-Length: 3\r\n\r\n"
98355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Yes");
98365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
98385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First round
98395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGet,
98405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Second round
98415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGetAuth,
98425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Third round
98435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGetAuth,
98445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fourth round
98455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGetAuth,
98465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Competing request
98475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kGet,
98485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
98495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
98505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First round
98515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kServerChallenge,
98525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Second round
98535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kServerChallenge,
98545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Third round
98555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kServerChallenge,
98565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Fourth round
98575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kSuccess,
98585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Competing response
98595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kSuccess,
98605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
98615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data_provider(reads, arraysize(reads),
98625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         writes, arraysize(writes));
9863c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
98645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kSocketGroup = "www.example.com:80";
98665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First round of authentication.
98685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->SetGenerateExpectation(false, OK);
98695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->Start(&request, callback.callback(), BoundNetLog());
98705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
98715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
98725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
98735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
98745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
98755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->auth_challenge.get() == NULL);
98765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
98775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In between rounds, another request comes in for the same domain.
98795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It should not be able to grab the TCP socket that trans has already
98805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // claimed.
98815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans_compete(
9882868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
98835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_compete;
98845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans_compete->Start(
98855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &request, callback_compete.callback(), BoundNetLog());
98865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
98875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // callback_compete.WaitForResult at this point would stall forever,
98885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // since the HttpNetworkTransaction does not release the request back to
98895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the pool until after authentication completes.
98905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second round of authentication.
98925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->SetGenerateExpectation(false, OK);
98935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
98945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
98955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
98965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
98975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
98985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
98995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
99005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
99015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Third round of authentication.
99035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->SetGenerateExpectation(false, OK);
99045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
99055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
99065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
99075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
99085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
99095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
99105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
99115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
99125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fourth round of authentication, which completes successfully.
99145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  auth_handler->SetGenerateExpectation(false, OK);
99155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
99165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
99175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
99185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
99195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans->GetResponseInfo();
99205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
99215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->auth_challenge.get() == NULL);
99225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
99235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read the body since the fourth round was successful. This will also
99255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // release the socket back to the pool.
99265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
9927868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
99285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
99295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
99305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, rv);
9931868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
99325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, rv);
99335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There are still 0 idle sockets, since the trans_compete transaction
99345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will be handed it immediately after trans releases it to the group.
99355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
99365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The competing request can now finish. Wait for the headers and then
99385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // read the body.
99395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback_compete.WaitForResult();
99405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
9941868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
99425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == ERR_IO_PENDING)
99435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
99445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3, rv);
9945868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
99465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, rv);
99475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finally, the socket is released to the group.
99495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
99505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
99515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This tests the case that a request is issued via http instead of spdy after
99535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// npn is negotiated.
99547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
9955cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
9956cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NextProtoVector next_protos;
9957ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  next_protos.push_back(kProtoHTTP11);
9958cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = next_protos;
9959cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
99605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
99615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
99625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
99635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
99645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes[] = {
99665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
99675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
99685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
99695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
99705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9971eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string alternate_protocol_http_header =
9972eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      GetAlternateProtocolHttpHeader();
9973eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
99745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
99755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
9976eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(alternate_protocol_http_header.c_str()),
99775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("hello world"),
99785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
99795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
99805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
99825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
99835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl.next_proto = "http/1.1";
99845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl.protocol_negotiated = kProtoHTTP11;
99855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
99875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
99895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                data_writes, arraysize(data_writes));
9990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
99915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
99935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
99952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
9996868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
99975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
99995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
100015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
100025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
100045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
10005868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
100065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
100075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
100095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
100105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
100115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
100135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
100145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
100155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
100175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate the SSL handshake completing with an NPN negotiation
100185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // followed by an immediate server closing of the socket.
100195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fix crash:  http://crbug.com/46369
10020cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
10021cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
100225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
100245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
100255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
100265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
100275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
100297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
10030c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
100315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1003290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
1003390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
100345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
100355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
100375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, 0, 0)   // Not async - return 0 immediately.
100385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
100395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
100415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0,  // don't wait in this case, immediate hangup.
100425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
100435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
10044c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
100455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
100475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10048c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
100492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10050868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
100515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
100535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
100545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
100555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
100565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10057ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// A subclass of HttpAuthHandlerMock that records the request URL when
10058ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// it gets it. This is needed since the auth handler may get destroyed
10059ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// before we get a chance to query it.
10060ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochclass UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10061ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch public:
10062ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10063ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
10064ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual ~UrlRecordingHttpAuthHandlerMock() {}
10065ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
10066ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch protected:
10067ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10068ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                    const HttpRequestInfo* request,
10069ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                    const CompletionCallback& callback,
10070ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                                    std::string* auth_token) OVERRIDE {
10071ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    *url_ = request->url;
10072ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10073ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        credentials, request, callback, auth_token);
10074ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
10075ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
10076ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch private:
10077ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  GURL* url_;
10078ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch};
10079ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
100807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
100815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This test ensures that the URL passed into the proxy is upgraded
100825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to https when doing an Alternate Protocol upgrade.
10083cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
10084cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
100855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10086c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
100872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
100882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog net_log;
10089c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &net_log;
10090ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  GURL request_url;
10091ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  {
10092ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    HttpAuthHandlerMock::Factory* auth_factory =
10093ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        new HttpAuthHandlerMock::Factory();
10094ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    UrlRecordingHttpAuthHandlerMock* auth_handler =
10095ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        new UrlRecordingHttpAuthHandlerMock(&request_url);
10096ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10097ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    auth_factory->set_do_init_from_challenge(true);
10098ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    session_deps_.http_auth_handler_factory.reset(auth_factory);
10099ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
101005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
101025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
101035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com");
101045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
101055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First round goes unauthenticated through the proxy.
101075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes_1[] = {
101085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
101095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
101105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
101115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
101125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
101135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads_1[] = {
101145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
101155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"
101165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Alternate-Protocol: 443:npn-spdy/2\r\n"
101175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "Proxy-Connection: close\r\n"
101185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             "\r\n"),
101195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
101205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
101215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  data_writes_1, arraysize(data_writes_1));
101225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second round tries to tunnel to www.google.com due to the
101245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Alternate-Protocol announcement in the first round. It fails due
101255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to a proxy authentication challenge.
101265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After the failure, a tunnel is established to www.google.com using
101275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Proxy-Authorization headers. There is then a SPDY request round.
101285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
101295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: Despite the "Proxy-Connection: Close", these are done on the
101305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
101315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // does a Disconnect and Connect on the same socket, rather than trying
101325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to obtain a new one.
101335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
101345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: Originally, the proxy response to the second CONNECT request
101355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // simply returned another 407 so the unit test could skip the SSL connection
101365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // establishment and SPDY framing issues. Alas, the
101375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // retry-http-when-alternate-protocol fails logic kicks in, which was more
101385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // complicated to set up expectations for than the SPDY session.
101395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1014090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
1014190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
101427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
101437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
101445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes_2[] = {
101465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First connection attempt without Proxy-Authorization.
101475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
101485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
101495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
101505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
101515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Second connection attempt with Proxy-Authorization.
101535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
101545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
101555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n"
101565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Authorization: auth_token\r\n"
101575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "\r\n"),
101585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SPDY request
101605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req),
101615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
101625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
101635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         "Proxy-Authenticate: Mock\r\n"
101645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         "Proxy-Connection: close\r\n"
101655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         "\r\n");
101665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
101675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads_2[] = {
101685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First connection attempt fails
101695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
101705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kRejectConnectResponse,
101715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(kRejectConnectResponse) - 1, 1),
101725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Second connection attempt passes
101745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, kAcceptConnectResponse,
101755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             arraysize(kAcceptConnectResponse) -1, 4),
101765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // SPDY response
101785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp.get(), 6),
101795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data.get(), 6),
101805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0, 6),
101815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
101825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data_2(
101835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_reads_2, arraysize(data_reads_2),
101845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data_writes_2, arraysize(data_writes_2));
101855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
101877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
101885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
101905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider hanging_non_alternate_protocol_socket(
101915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL, 0, NULL, 0);
101925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hanging_non_alternate_protocol_socket.set_connect_data(
101935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      never_finishing_connect);
101945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data_1);
10196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data_2);
10197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(
101995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &hanging_non_alternate_protocol_socket);
10200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
102015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First round should work and provide the Alternate-Protocol state.
102035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_1;
102042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans_1(
10205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
102065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
102075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
102085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback_1.WaitForResult());
102095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Second round should attempt a tunnel connect and get an auth challenge.
102115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_2;
102122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans_2(
10213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
102145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
102155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
102165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback_2.WaitForResult());
102175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans_2->GetResponseInfo();
102185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
102195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(response->auth_challenge.get() == NULL);
102205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restart with auth. Tunnel should work and response received.
102225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback_3;
102235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans_2->RestartWithAuth(
102245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AuthCredentials(kFoo, kBar), callback_3.callback());
102255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
102265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback_3.WaitForResult());
102275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // After all that work, these two lines (or actually, just the scheme) are
102295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // what this test is all about. Make sure it happens correctly.
102305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("https", request_url.scheme());
102315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("www.google.com", request_url.host());
102325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
102342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
102352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
102362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
102375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
102385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that if we cancel the transaction as the connection is completing, that
102405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// everything tears down correctly.
102417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
102425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setup everything about the connection to complete synchronously, so that
102435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // after calling HttpNetworkTransaction::Start, the only thing we're waiting
102445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for is the callback from the HttpStreamRequest.
102455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Then cancel the transaction.
102465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that we don't crash.
102475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect mock_connect(SYNCHRONOUS, OK);
102485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads[] = {
102495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
102505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, "hello world"),
102515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
102525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
102535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
102555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
102565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
102575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
102585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->set_synchronous_mode(true);
102608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
102615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
102628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
102635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
102655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data.set_connect_data(mock_connect);
10266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
102675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
102695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
102715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), log.bound());
102725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
102735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trans.reset();  // Cancel the transaction here.
102745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1027590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
102765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
102775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Test that if a transaction is cancelled after receiving the headers, the
10279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// stream is drained properly and added back to the socket pool.  The main
10280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// purpose of this test is to make sure that an HttpStreamParser can be read
10281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// from after the HttpNetworkTransaction and the objects it owns have been
10282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// deleted.
10283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// See http://crbug.com/368418
10284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
10285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MockRead data_reads[] = {
10286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
10287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockRead(ASYNC, "Content-Length: 2\r\n"),
10288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
10289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockRead(ASYNC, "1"),
10290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // 2 async reads are necessary to trigger a ReadResponseBody call after the
10291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // HttpNetworkTransaction has been deleted.
10292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockRead(ASYNC, "2"),
10293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_IO_PENDING),  // Should never read this.
10294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  };
10295cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
10297cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10298cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10299cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  {
10301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    HttpRequestInfo request;
10302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    request.method = "GET";
10303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    request.url = GURL("http://www.google.com/");
10304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    request.load_flags = 0;
10305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
10307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    TestCompletionCallback callback;
10308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int rv = trans.Start(&request, callback.callback(), BoundNetLog());
10310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING, rv);
10311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    callback.WaitForResult();
10312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const HttpResponseInfo* response = trans.GetResponseInfo();
10314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ASSERT_TRUE(response != NULL);
10315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_TRUE(response->headers.get() != NULL);
10316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // The transaction and HttpRequestInfo are deleted.
10319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
10320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Let the HttpResponseBodyDrainer drain the socket.
10322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
10323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
10324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Socket should now be idle, waiting to be reused.
10325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
10326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
10327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
103285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a basic GET request through a proxy.
103297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ProxyGet) {
10330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
103312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
103325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
10333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
10334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
103355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
103375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
103385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("http://www.google.com/");
103395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
103415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
103425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
103435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
103445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
103455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
103475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
103485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
103495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
103505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
103515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
103525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
103545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
10355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
103565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
103585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10361116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  BeforeProxyHeadersSentHandler proxy_headers_handler;
10362116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  trans->SetBeforeProxyHeadersSentCallback(
10363116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
10364116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::Unretained(&proxy_headers_handler)));
103655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
103675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
103685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
103705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
103715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
103735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
103745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
103765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
103775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
103785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_proxy);
10379f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(
10380f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
10381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
10382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
103835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
103842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
103852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
103862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
103872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
103882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
103895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
103905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a basic HTTPS GET request through a proxy.
103927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
10393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
103942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
103955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
10396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
10397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
103985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
104005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
104015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
104025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
104045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
104055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
104065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
104075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
104085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
104105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
104115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
104125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
104135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
104155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
104165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
104185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
104195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("Content-Length: 100\r\n\r\n"),
104205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
104215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
104225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
104245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
10425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
104265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
10427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
104285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
104305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
104335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
104355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
104365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
104385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
104395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
104405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
104415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
104425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
104435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
104445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
104455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
104465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
104475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
104485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
104505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
104515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->headers->IsKeepAlive());
104535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response->headers->response_code());
104545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(100, response->headers->GetContentLength());
104555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
104565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_proxy);
10457f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(
10458f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
104592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
104602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info;
104612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
104622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info,
104632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
104645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
104655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test a basic HTTPS GET request through a proxy, but the server hangs up
104675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// while establishing the tunnel.
104687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
10469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
104705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
10471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
10472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
104735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
104755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
104765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
104775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since we have proxy, should try to establish tunnel.
104795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite data_writes1[] = {
104805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
104815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
104825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Proxy-Connection: keep-alive\r\n\r\n"),
104835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
104855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com\r\n"
104865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
104875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
104885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead data_reads1[] = {
104905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
104915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
104925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),  // EOF
104935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
104945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
104955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
104965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 data_writes1, arraysize(data_writes1));
10497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
104985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
10499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
105005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
105025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10504868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
105055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback1.callback(), log.bound());
105075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
105085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback1.WaitForResult();
105105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
105115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CapturingNetLog::CapturedEntryList entries;
105125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  log.GetEntries(&entries);
105135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = ExpectLogContainsSomewhere(
105145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
105155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
105165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExpectLogContainsSomewhere(
105175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      entries, pos,
105185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
105195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NetLog::PHASE_NONE);
105205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
105215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test for crbug.com/55424.
105237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
1052490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req(
1052590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
105265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = { CreateMockWrite(*req) };
105275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
105297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
105305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
105315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp),
105325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*data),
105335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 0),
105345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
105355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData spdy_data(
105375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,  // wait for one write to finish before reading.
105385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
105395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
10540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
105415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
105437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
10544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
105455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
105475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up an initial SpdySession in the pool to reuse.
105495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair host_port_pair("www.google.com", 443);
1055090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
10551e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                     PRIVACY_MODE_DISABLED);
10552ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  base::WeakPtr<SpdySession> spdy_session =
105537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      CreateInsecureSpdySession(session, key, BoundNetLog());
105545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request;
105565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.method = "GET";
105575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.url = GURL("https://www.google.com/");
105585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.load_flags = 0;
105595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is the important line that marks this as a preconnect.
105615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
105625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10564868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
105655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TestCompletionCallback callback;
105675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
105685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
105695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
105705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
105715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Given a net error, cause that error to be returned from the first Write()
105735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// call and verify that the HttpTransaction fails with that error.
105747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
10575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int error, IoMode mode) {
105765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestInfo request_info;
105775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.url = GURL("https://www.example.com/");
105785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.method = "GET";
105795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.load_flags = net::LOAD_NORMAL;
105805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data(mode, OK);
105825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::MockWrite data_writes[] = {
105835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::MockWrite(mode, error),
105845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
105855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data(NULL, 0,
105865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     data_writes, arraysize(data_writes));
10587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
10588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
105895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
105912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10592868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
105935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
105955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
105965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rv == net::ERR_IO_PENDING)
105975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
105985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(error, rv);
105995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
106005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
106025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Just check a grab bag of cert errors.
106035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kErrors[] = {
106045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ERR_CERT_COMMON_NAME_INVALID,
106055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ERR_CERT_AUTHORITY_INVALID,
106065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ERR_CERT_DATE_INVALID,
106075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
106085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kErrors); i++) {
106095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckErrorIsPassedBack(kErrors[i], ASYNC);
106105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
106115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
106125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
106135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure that a client certificate is removed from the SSL client auth
106155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cache when:
106165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  1) No proxy is involved.
106175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  2) TLS False Start is disabled.
106185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  3) The initial TLS handshake requests a client certificate.
106195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  4) The client supplies an invalid/unacceptable certificate.
106207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
106215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ClientAuthCertCache_Direct_NoFalseStart) {
106225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestInfo request_info;
106235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.url = GURL("https://www.example.com/");
106245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.method = "GET";
106255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.load_flags = net::LOAD_NORMAL;
106265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
106285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cert_request->host_and_port = HostPortPair("www.example.com", 443);
106295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data1 contains the data for the first SSL handshake. When a
106315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CertificateRequest is received for the first time, the handshake will
106325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be aborted to allow the caller to provide a certificate.
106335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
106345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data1.cert_request_info = cert_request.get();
10635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
106365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
106385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data2 contains the data for the second SSL handshake. When TLS
106405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // False Start is not being used, the result of the SSL handshake will be
106415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // returned as part of the SSLClientSocket::Connect() call. This test
106425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // matches the result of a server sending a handshake_failure alert,
106435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // rather than a Finished message, because it requires a client
106445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate and none was supplied.
106455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
106465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data2.cert_request_info = cert_request.get();
10647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
106485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
10649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
106505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data3 contains the data for the third SSL handshake. When a
106525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection to a server fails during an SSL handshake,
106535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
106545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection was attempted with TLSv1.1. This is transparent to the caller
106555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the HttpNetworkTransaction. Because this test failure is due to
106565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // requiring a client certificate, this fallback handshake should also
106575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fail.
106585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
106595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data3.cert_request_info = cert_request.get();
10660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
106615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
10662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
106635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data4 contains the data for the fourth SSL handshake. When a
106655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection to a server fails during an SSL handshake,
106665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
106675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // connection was attempted with TLSv1. This is transparent to the caller
106685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the HttpNetworkTransaction. Because this test failure is due to
106695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // requiring a client certificate, this fallback handshake should also
106705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // fail.
106715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
106725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data4.cert_request_info = cert_request.get();
10673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
106745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
10675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data4);
106765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10677868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Need one more if TLSv1.2 is enabled.
10678868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
10679868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ssl_data5.cert_request_info = cert_request.get();
10680868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10681868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
10682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data5);
10683868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
106852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10686868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
106875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Begin the SSL handshake with the peer. This consumes ssl_data1.
106895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
106905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
106915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_IO_PENDING, rv);
106925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the SSL handshake, which should abort due to requiring a
106945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // client certificate.
106955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
106965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
106975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
106985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Indicate that no certificate should be supplied. From the perspective
106995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of SSLClientCertCache, NULL is just as meaningful as a real
107005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate, so this is the same as supply a
107015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // legitimate-but-unacceptable certificate.
107025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithCertificate(NULL, callback.callback());
107035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_IO_PENDING, rv);
107045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure the certificate was added to the client auth cache before
107065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // allowing the connection to continue restarting.
107075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> client_cert;
107085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
107095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      HostPortPair("www.example.com", 443), &client_cert));
107105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(NULL, client_cert.get());
107115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restart the handshake. This will consume ssl_data2, which fails, and
107135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // then consume ssl_data3 and ssl_data4, both of which should also fail.
107145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The result code is checked against what ssl_data4 should return.
107155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
107165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
107175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that the client certificate is removed from the cache on a
107195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // handshake failure.
107205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
107215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      HostPortPair("www.example.com", 443), &client_cert));
107225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
107235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure that a client certificate is removed from the SSL client auth
107255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cache when:
107265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  1) No proxy is involved.
107275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  2) TLS False Start is enabled.
107285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  3) The initial TLS handshake requests a client certificate.
107295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  4) The client supplies an invalid/unacceptable certificate.
107307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest,
107315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ClientAuthCertCache_Direct_FalseStart) {
107325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestInfo request_info;
107335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.url = GURL("https://www.example.com/");
107345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.method = "GET";
107355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request_info.load_flags = net::LOAD_NORMAL;
107365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
107385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cert_request->host_and_port = HostPortPair("www.example.com", 443);
107395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When TLS False Start is used, SSLClientSocket::Connect() calls will
107415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // return successfully after reading up to the peer's Certificate message.
107425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is to allow the caller to call SSLClientSocket::Write(), which can
107435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // enqueue application data to be sent in the same packet as the
107445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ChangeCipherSpec and Finished messages.
107455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The actual handshake will be finished when SSLClientSocket::Read() is
107465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called, which expects to process the peer's ChangeCipherSpec and
107475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Finished messages. If there was an error negotiating with the peer,
107485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // such as due to the peer requiring a client certificate when none was
107495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // supplied, the alert sent by the peer won't be processed until Read() is
107505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called.
107515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Like the non-False Start case, when a client certificate is requested by
107535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the peer, the handshake is aborted during the Connect() call.
107545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data1 represents the initial SSL handshake with the peer.
107555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
107565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data1.cert_request_info = cert_request.get();
10757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
107585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
107605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When a client certificate is supplied, Connect() will not be aborted
107625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the peer requests the certificate. Instead, the handshake will
107635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // artificially succeed, allowing the caller to write the HTTP request to
107645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the socket. The handshake messages are not processed until Read() is
107655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called, which then detects that the handshake was aborted, due to the
107665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // peer sending a handshake_failure because it requires a client
107675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate.
107685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
107695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data2.cert_request_info = cert_request.get();
10770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
107715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::MockRead data2_reads[] = {
107725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
107735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
107745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data2(
107755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data2_reads, arraysize(data2_reads), NULL, 0);
10776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
107775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
107795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the data for the SSL handshake once the TLSv1.1 connection falls back to
107805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TLSv1. It has the same behaviour as [ssl_]data2.
107815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
107825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data3.cert_request_info = cert_request.get();
10783c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
107845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data3(
107855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data2_reads, arraysize(data2_reads), NULL, 0);
10786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
107875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
107895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
107905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
107915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data4.cert_request_info = cert_request.get();
10792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
107935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data4(
107945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data2_reads, arraysize(data2_reads), NULL, 0);
10795c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data4);
107965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10797868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Need one more if TLSv1.2 is enabled.
10798868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
10799868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ssl_data5.cert_request_info = cert_request.get();
10800868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
10801868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  net::StaticSocketDataProvider data5(
10802868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      data2_reads, arraysize(data2_reads), NULL, 0);
10803868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data5);
10804868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
10805c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
108062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<HttpTransaction> trans(
10807868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
108085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Begin the initial SSL handshake.
108105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
108115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
108125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_IO_PENDING, rv);
108135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Complete the SSL handshake, which should abort due to requiring a
108155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // client certificate.
108165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
108175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
108185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Indicate that no certificate should be supplied. From the perspective
108205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of SSLClientCertCache, NULL is just as meaningful as a real
108215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // certificate, so this is the same as supply a
108225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // legitimate-but-unacceptable certificate.
108235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans->RestartWithCertificate(NULL, callback.callback());
108245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_IO_PENDING, rv);
108255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure the certificate was added to the client auth cache before
108275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // allowing the connection to continue restarting.
108285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> client_cert;
108295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
108305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      HostPortPair("www.example.com", 443), &client_cert));
108315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(NULL, client_cert.get());
108325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Restart the handshake. This will consume ssl_data2, which fails, and
108345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // then consume ssl_data3 and ssl_data4, both of which should also fail.
108355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The result code is checked against what ssl_data4 should return.
108365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
108375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
108385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that the client certificate is removed from the cache on a
108405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // handshake failure.
108415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
108425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      HostPortPair("www.example.com", 443), &client_cert));
108435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
108445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure that a client certificate is removed from the SSL client auth
108465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cache when:
108475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  1) An HTTPS proxy is involved.
108485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  3) The HTTPS proxy requests a client certificate.
108495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  4) The client supplies an invalid/unacceptable certificate for the
108505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     proxy.
108515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The test is repeated twice, first for connecting to an HTTPS endpoint,
108525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// then for connecting to an HTTP endpoint.
108537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
10854c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
108555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ProxyService::CreateFixed("https://proxy:70"));
108565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingBoundNetLog log;
10857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = log.bound().net_log();
108585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
108605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cert_request->host_and_port = HostPortPair("proxy", 70);
108615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
108635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // [ssl_]data[1-3]. Rather than represending the endpoint
108645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (www.example.com:443), they represent failures with the HTTPS proxy
108655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (proxy:70).
108665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
108675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data1.cert_request_info = cert_request.get();
10868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
108695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
10870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
108715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
108735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data2.cert_request_info = cert_request.get();
10874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
108755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
10876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
108775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
108795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0
108805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
108815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_data3.cert_request_info = cert_request.get();
10882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
108835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
10884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data3);
108855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
108865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::HttpRequestInfo requests[2];
108885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[0].url = GURL("https://www.example.com/");
108895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[0].method = "GET";
108905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[0].load_flags = net::LOAD_NORMAL;
108915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[1].url = GURL("http://www.example.com/");
108935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[1].method = "GET";
108945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  requests[1].load_flags = net::LOAD_NORMAL;
108955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(requests); ++i) {
10897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    session_deps_.socket_factory->ResetNextMockIndexes();
10898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
108995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpNetworkTransaction> trans(
10900868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
109015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Begin the SSL handshake with the proxy.
109035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestCompletionCallback callback;
109045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = trans->Start(
109055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &requests[i], callback.callback(), net::BoundNetLog());
109065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(net::ERR_IO_PENDING, rv);
109075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Complete the SSL handshake, which should abort due to requiring a
109095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // client certificate.
109105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
109115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
109125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Indicate that no certificate should be supplied. From the perspective
109145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // of SSLClientCertCache, NULL is just as meaningful as a real
109155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // certificate, so this is the same as supply a
109165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // legitimate-but-unacceptable certificate.
109175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = trans->RestartWithCertificate(NULL, callback.callback());
109185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(net::ERR_IO_PENDING, rv);
109195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ensure the certificate was added to the client auth cache before
109215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // allowing the connection to continue restarting.
109225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<X509Certificate> client_cert;
109235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
109245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        HostPortPair("proxy", 70), &client_cert));
109255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(NULL, client_cert.get());
109265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ensure the certificate was NOT cached for the endpoint. This only
109275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // applies to HTTPS requests, but is fine to check for HTTP requests.
109285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
109295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        HostPortPair("www.example.com", 443), &client_cert));
109305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Restart the handshake. This will consume ssl_data2, which fails, and
109325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // then consume ssl_data3, which should also fail. The result code is
109335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // checked against what ssl_data3 should return.
109345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rv = callback.WaitForResult();
109355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
109365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Now that the new handshake has failed, ensure that the client
109385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // certificate was removed from the client auth cache.
109395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
109405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        HostPortPair("proxy", 70), &client_cert));
109415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
109425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        HostPortPair("www.example.com", 443), &client_cert));
109435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
109445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
109455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Unlike TEST/TEST_F, which are macros that expand to further macros,
109477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// TEST_P is a macro that expands directly to code that stringizes the
109487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// arguments. As a result, macros passed as parameters (such as prefix
109497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// or test_case_name) will not be expanded by the preprocessor. To
109507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// work around this, indirect the macro for TEST_P, so that the
109517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// pre-processor will expand macros such as MAYBE_test_name before
109527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// instantiating the test.
109537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#define WRAPPED_TEST_P(test_case_name, test_name) \
109547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  TEST_P(test_case_name, test_name)
109557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
109565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Times out on Win7 dbg(2) bot. http://crbug.com/124776
109575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
109585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
109595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
109605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
109615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
109627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
10963cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
10964cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
109655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a special HttpNetworkSession with a MockCachingHostResolver.
10967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver.reset(new MockCachingHostResolver());
10968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
109695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
109705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pool_peer.DisableDomainAuthenticationVerification();
109715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
109737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
10974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
109755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1097690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host1_req(
1097790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
1097890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host2_req(
1097990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
109805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
109815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host1_req, 1),
109825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host2_req, 4),
109835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
109847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp(
109857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
109867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp_body(
109877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
109887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp(
109897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
109907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp_body(
109917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, true));
109925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
109935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp, 2),
109945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp_body, 3),
109955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp, 5),
109965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp_body, 6),
109975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 7),
109985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
109995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip;
110015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
110025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint peer_addr = IPEndPoint(ip, 443);
110035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect(ASYNC, OK, peer_addr);
110045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
110055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      connect,
110065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
110075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
11008c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
110095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
110115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
110125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
110135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL("https://www.google.com/");
110145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11015868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
110165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
110185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
110195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
110205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans1.GetResponseInfo();
110225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11023868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
110245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
110255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
110275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
110285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
110295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preload www.gmail.com into HostCache.
110315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostPortPair host_port("www.gmail.com", 443);
110325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostResolver::RequestInfo resolve_info(host_port);
110335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList ignored;
110343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  rv = session_deps_.host_resolver->Resolve(resolve_info,
110353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            DEFAULT_PRIORITY,
110363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            &ignored,
110373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            callback.callback(),
110383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            NULL,
110393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                            BoundNetLog());
110405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
110415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
110425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
110435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
110455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
110465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL("https://www.gmail.com/");
110475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11048868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
110495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
110515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
110525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
110535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans2.GetResponseInfo();
110555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11056868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
110575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
110585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
110595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
110605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
110615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
110625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
110635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef MAYBE_UseIPConnectionPooling
110645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
11066cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
11067cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
110685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a special HttpNetworkSession with a MockCachingHostResolver.
11070c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver.reset(new MockCachingHostResolver());
11071c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
110725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
110735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pool_peer.DisableDomainAuthenticationVerification();
110745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
110755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
110767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
11077c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
110785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1107990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host1_req(
1108090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
1108190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host2_req(
1108290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
110835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
110845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host1_req, 1),
110855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host2_req, 4),
110865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
110877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp(
110887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
110897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp_body(
110907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
110917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp(
110927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
110937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp_body(
110947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, true));
110955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
110965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp, 2),
110975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp_body, 3),
110985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp, 5),
110995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp_body, 6),
111005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 7),
111015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
111025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip;
111045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
111055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint peer_addr = IPEndPoint(ip, 443);
111065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect(ASYNC, OK, peer_addr);
111075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
111085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      connect,
111095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
111105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
11111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
111125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
111145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
111155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
111165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL("https://www.google.com/");
111175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
111195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
111215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
111225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
111235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans1.GetResponseInfo();
111255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
111275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
111285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
111305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
111315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
111325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
111345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
111355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL("https://www.gmail.com/");
111365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
111385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
111405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
111415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
111425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans2.GetResponseInfo();
111445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
111465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
111475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
111485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
111495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
111505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
111515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
111525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OneTimeCachingHostResolver : public net::HostResolver {
111545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
111555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
111565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : host_port_(host_port) {}
111575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~OneTimeCachingHostResolver() {}
111585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
111605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HostResolver methods:
111625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int Resolve(const RequestInfo& info,
111633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                      RequestPriority priority,
111645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      AddressList* addresses,
111655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const CompletionCallback& callback,
111665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      RequestHandle* out_req,
111675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const BoundNetLog& net_log) OVERRIDE {
111685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return host_resolver_.Resolve(
111693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        info, priority, addresses, callback, out_req, net_log);
111705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
111715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int ResolveFromCache(const RequestInfo& info,
111735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               AddressList* addresses,
111745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const BoundNetLog& net_log) OVERRIDE {
111755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
111765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv == OK && info.host_port_pair().Equals(host_port_))
111775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      host_resolver_.GetHostCache()->clear();
111785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return rv;
111795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
111805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CancelRequest(RequestHandle req) OVERRIDE {
111825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    host_resolver_.CancelRequest(req);
111835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
111845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockCachingHostResolver* GetMockHostResolver() {
111865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &host_resolver_;
111875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
111885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
111905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockCachingHostResolver host_resolver_;
111915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HostPortPair host_port_;
111925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
111935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Times out on Win7 dbg(2) bot. http://crbug.com/124776
111955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
11196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
111985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
11199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
11200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    UseIPConnectionPoolingWithHostCacheExpiration
112015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
112027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)WRAPPED_TEST_P(HttpNetworkTransactionTest,
112037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)               MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
112047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
112057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// prefix doesn't work with parametrized tests).
112067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN)
112077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return;
1120823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#else
11209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.use_alternate_protocols = true;
11210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
112115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
112135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
112142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HttpNetworkSession::Params params =
11215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::CreateSessionParams(&session_deps_);
112165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.host_resolver = &host_resolver;
11217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
112185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
112195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pool_peer.DisableDomainAuthenticationVerification();
112205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
112227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
11223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
112245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1122590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host1_req(
1122690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
1122790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host2_req(
1122890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
112295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite spdy_writes[] = {
112305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host1_req, 1),
112315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*host2_req, 4),
112325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
112337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp(
112347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
112357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp_body(
112367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
112377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp(
112387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
112397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp_body(
112407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(3, true));
112415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead spdy_reads[] = {
112425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp, 2),
112435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host1_resp_body, 3),
112445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp, 5),
112455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*host2_resp_body, 6),
112465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 0, 7),
112475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
112485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip;
112505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
112515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint peer_addr = IPEndPoint(ip, 443);
112525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect(ASYNC, OK, peer_addr);
112535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData spdy_data(
112545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      connect,
112555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_reads, arraysize(spdy_reads),
112565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      spdy_writes, arraysize(spdy_writes));
11257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
112585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback;
112605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
112615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
112625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL("https://www.google.com/");
112635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
112655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
112675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
112685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
112695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const HttpResponseInfo* response = trans1.GetResponseInfo();
112715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
112735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
112745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string response_data;
112765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
112775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
112785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Preload cache entries into HostCache.
112805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
112815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddressList ignored;
112823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  rv = host_resolver.Resolve(resolve_info,
112833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             DEFAULT_PRIORITY,
112843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             &ignored,
112853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             callback.callback(),
112863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             NULL,
112873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             BoundNetLog());
112885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
112895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = callback.WaitForResult();
112905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, rv);
112915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
112935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
112945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL("https://www.gmail.com/");
112955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
112975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
112995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
113005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
113015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response = trans2.GetResponseInfo();
113035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(response != NULL);
11304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
113055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
113065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
113075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
113085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
113095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("hello!", response_data);
1131023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#endif
113115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
113125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
113135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
113155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string https_url = "https://www.google.com/";
113165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string http_url = "http://www.google.com:443/";
113175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTPS URL
1131990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(
1132090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
113215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes1[] = {
113235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req1, 0),
113245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
113255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
113277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
113285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads1[] = {
113295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp1, 1),
113305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body1, 2),
113315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 3)
113325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
113335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data1(
113355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1, reads1, arraysize(reads1),
113365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writes1, arraysize(writes1));
113375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect_data1(ASYNC, OK);
113385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1.set_connect_data(connect_data1);
113395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HTTP GET for the HTTP URL
113415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes2[] = {
113425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockWrite(ASYNC, 4,
113435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "GET / HTTP/1.1\r\n"
113445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Host: www.google.com:443\r\n"
113455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
113465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
113475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads2[] = {
113495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
113505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 6, "hello"),
113515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, 7, OK),
113525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
113535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DelayedSocketData data2(
113555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1, reads2, arraysize(reads2),
113565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      writes2, arraysize(writes2));
113575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
113597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
11360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data1);
11362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data2);
113635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
113655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first transaction to set up the SpdySession
113675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
113685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
113695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL(https_url);
113705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(LOWEST, session.get());
113725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
113735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
113745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
1137590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
113765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
113785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
113795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, start the HTTP request
113815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
113825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
113835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL(http_url);
113845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
113865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
113875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
113885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1138990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
113905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
113925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
113935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
113945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
113965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string https_url = "https://www.google.com/";
113975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string http_url = "http://www.google.com:443/";
113985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
113995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTPS URL (through CONNECT tunnel)
114003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
114013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                                LOWEST));
1140290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(
1140390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
114047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_req1(
114057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
11406c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
11407c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
11408116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SpdyHeaderBlock req2_block;
11409116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  req2_block[spdy_util_.GetMethodKey()] = "GET";
11410116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  req2_block[spdy_util_.GetPathKey()] =
11411116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      spdy_util_.is_spdy2() ? http_url.c_str() : "/";
11412116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  req2_block[spdy_util_.GetHostKey()] = "www.google.com:443";
11413116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  req2_block[spdy_util_.GetSchemeKey()] = "http";
11414116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  spdy_util_.MaybeAddVersionHeader(&req2_block);
11415c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_ptr<SpdyFrame> req2(
11416116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
114175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes1[] = {
114195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*connect, 0),
114205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*wrapped_req1, 2),
114215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2, 5),
114225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
114235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> conn_resp(
114257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
114267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
114277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
114287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_resp1(
114297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
114307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> wrapped_body1(
114317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
114327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
114337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
114345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads1[] = {
114355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*conn_resp, 1),
114365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_resp1, 3),
114375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*wrapped_body1, 4),
114385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2, 6),
114395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2, 7),
114405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 8)
114415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
114425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DeterministicSocketData data1(reads1, arraysize(reads1),
114445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                writes1, arraysize(writes1));
114455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect_data1(ASYNC, OK);
114465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1.set_connect_data(connect_data1);
114475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(
114492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
114502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CapturingNetLog log;
11451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.net_log = &log;
114525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
114537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl1.SetNextProto(GetParam());
11454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
114555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
114567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
11457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
114595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
11461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
114625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first transaction to set up the SpdySession
114645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
114655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
114665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL(https_url);
114675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(LOWEST, session.get());
114695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
114705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
114715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
1147290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
114735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1.RunFor(4);
114745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
114765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
114775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info1;
114792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
114802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingNotReusedWithPac(load_timing_info1,
114812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 CONNECT_TIMING_HAS_SSL_TIMES);
114822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
114835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, start the HTTP request
114845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
114855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
114865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL(http_url);
114875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11488868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
114895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
114905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
114915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1149290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
114935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1.RunFor(3);
114945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
114955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
114965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
114972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
114982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadTimingInfo load_timing_info2;
114992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
115002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The established SPDY sessions is considered reused by the HTTP request.
115012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestLoadTimingReusedWithPac(load_timing_info2);
115022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // HTTP requests over a SPDY session should have a different connection
115032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // socket_log_id than requests over a tunnel.
115042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
115055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
115065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
11508cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.force_spdy_always = true;
115095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string https_url = "https://www.google.com/";
115105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string http_url = "http://www.google.com:443/";
115115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTPS URL
1151390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req1(
1151490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
115155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for the HTTP URL
1151690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
1151790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
115185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes[] = {
115205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req1, 1),
115215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2, 4),
115225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
115235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
115257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
115267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
115277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
115285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads[] = {
115295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp1, 2),
115305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body1, 3),
115315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2, 5),
115325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2, 6),
115335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 7)
115345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
115355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OrderedSocketData data(reads, arraysize(reads),
115375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         writes, arraysize(writes));
115385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
115407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl.SetNextProto(GetParam());
11541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&data);
115435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
115455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first transaction to set up the SpdySession
115475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
115485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
115495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL(https_url);
115505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11551868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(LOWEST, session.get());
115525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
115535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
115545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
1155590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
115565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
115585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
115595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, start the HTTP request
115615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
115625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
115635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL(http_url);
115645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11565868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
115665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
115675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
115685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1156990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
115705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
115725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
115735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
115745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that in the case where we have a SPDY session to a SPDY proxy
115765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that we do not pool other origins that resolve to the same IP when
115775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the certificate does not match the new origin.
115785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/134690
115797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
115805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string url1 = "http://www.google.com/";
115815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string url2 = "https://mail.google.com/";
115825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string ip_addr = "1.2.3.4";
115835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTP URL (through SPDY proxy)
115857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyHeaderBlock> headers(
115867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
11587116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<SpdyFrame> req1(
11588116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
115895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes1[] = {
115915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req1, 0),
115925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
115935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
115957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
115965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads1[] = {
115975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp1, 1),
115985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body1, 2),
115995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK, 3) // EOF
116005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
116015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeterministicSocketData> data1(
116035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new DeterministicSocketData(reads1, arraysize(reads1),
116045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  writes1, arraysize(writes1)));
116055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPAddressNumber ip;
116065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
116075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPEndPoint peer_addr = IPEndPoint(ip, 443);
116085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect_data1(ASYNC, OK, peer_addr);
116095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1->set_connect_data(connect_data1);
116105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SPDY GET for HTTPS URL (direct)
1161290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
1161390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
116145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockWrite writes2[] = {
116165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockWrite(*req2, 0),
116175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
116185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
116207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
116215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRead reads2[] = {
116225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*resp2, 1),
116235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateMockRead(*body2, 2),
116245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockRead(ASYNC, OK, 3) // EOF
116255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
116265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DeterministicSocketData> data2(
116285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new DeterministicSocketData(reads2, arraysize(reads2),
116295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  writes2, arraysize(writes2)));
116305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockConnect connect_data2(ASYNC, OK);
116315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data2->set_connect_data(connect_data2);
116325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set up a proxy config that sends HTTP requests to a proxy, and
116345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // all others direct.
116355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyConfig proxy_config;
116365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
116375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CapturingProxyResolver* capturing_proxy_resolver =
116385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new CapturingProxyResolver();
11639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.proxy_service.reset(new ProxyService(
116405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
116415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL));
116425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load a valid cert.  Note, that this does not need to
116445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be valid for proxy because the MockSSLClientSocket does
116455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not actually verify it.  But SpdySession will use this
116465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to see if it is valid for the new origin
116472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath certs_dir = GetTestCertsDirectory();
116485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<X509Certificate> server_cert(
116495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ImportCertFromFile(certs_dir, "ok_cert.pem"));
116505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
116515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
116537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl1.SetNextProto(GetParam());
116545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl1.cert = server_cert;
11655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data1.get());
116585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
116607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
11661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data2.get());
116645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver.reset(new MockCachingHostResolver());
11666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
11667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
116685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
11670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
116715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start the first transaction to set up the SpdySession
116735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request1;
116745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.method = "GET";
116755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.url = GURL(url1);
116765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request1.load_flags = 0;
11677868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(LOWEST, session.get());
116785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback1;
116795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING,
116805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
116815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data1->RunFor(3);
116825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(callback1.have_result());
116845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback1.WaitForResult());
116855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
116865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now, start the HTTP request
116885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpRequestInfo request2;
116895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.method = "GET";
116905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.url = GURL(url2);
116915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  request2.load_flags = 0;
11692868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
116935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback2;
116945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
116955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1169690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
116975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data2->RunFor(3);
116985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
116995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(callback2.have_result());
117005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
117015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
117025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
117035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
11705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// error) in SPDY session, removes the socket from pool and closes the SPDY
11706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// session. Verify that new url's from the same HttpNetworkSession (and a new
11707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// SpdySession) do work. http://crbug.com/224701
117087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
11709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const std::string https_url = "https://www.google.com/";
11710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockRead reads1[] = {
11712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
11713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
11714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DeterministicSocketData> data1(
11716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
11717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  data1->SetStop(1);
11718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1171990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> req2(
1172090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
11721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockWrite writes2[] = {
11722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CreateMockWrite(*req2, 0),
11723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
11724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
117257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
117267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
11727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockRead reads2[] = {
11728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CreateMockRead(*resp2, 1),
11729c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CreateMockRead(*body2, 2),
11730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    MockRead(ASYNC, OK, 3)  // EOF
11731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
11732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<DeterministicSocketData> data2(
11734c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new DeterministicSocketData(reads2, arraysize(reads2),
11735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  writes2, arraysize(writes2)));
11736c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SSLSocketDataProvider ssl1(ASYNC, OK);
117387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl1.SetNextProto(GetParam());
11739c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
11740c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11741c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data1.get());
11742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11743c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
117447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
11745c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
11746c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  session_deps_.deterministic_socket_factory->AddSocketDataProvider(
11747c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      data2.get());
11748c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11749c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(
11750c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
11751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Start the first transaction to set up the SpdySession and verify that
11753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // connection was closed.
11754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HttpRequestInfo request1;
11755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request1.method = "GET";
11756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request1.url = GURL(https_url);
11757c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request1.load_flags = 0;
11758868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans1(MEDIUM, session.get());
11759c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback1;
11760c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
11761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            trans1.Start(&request1, callback1.callback(), BoundNetLog()));
1176290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
11763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
11764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Now, start the second request and make sure it succeeds.
11766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  HttpRequestInfo request2;
11767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request2.method = "GET";
11768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request2.url = GURL(https_url);
11769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  request2.load_flags = 0;
11770868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  HttpNetworkTransaction trans2(MEDIUM, session.get());
11771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TestCompletionCallback callback2;
11772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
11773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            trans2.Start(&request2, callback2.callback(), BoundNetLog()));
1177490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->RunUntilIdle();
11775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  data2->RunFor(3);
11776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11777c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_TRUE(callback2.have_result());
11778c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(OK, callback2.WaitForResult());
11779c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
11780c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
11781c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
117827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
11783cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  session_deps_.next_protos = SpdyNextProtos();
11784a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_group(
11785a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11786a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_pool(
11787a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
11788a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11789a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Use two different hosts with different IPs so they don't get pooled.
11790a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
11791a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
11792a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11793a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11794a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SSLSocketDataProvider ssl1(ASYNC, OK);
117957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl1.SetNextProto(GetParam());
11796a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  SSLSocketDataProvider ssl2(ASYNC, OK);
117977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ssl2.SetNextProto(GetParam());
11798a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
11799a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
11800a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1180190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
11802a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      "https://www.a.com", false, 1, DEFAULT_PRIORITY));
11803a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockWrite spdy1_writes[] = {
11804a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockWrite(*host1_req, 1),
11805a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
118067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp(
118077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
118087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host1_resp_body(
118097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
11810a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockRead spdy1_reads[] = {
11811a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockRead(*host1_resp, 2),
11812a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockRead(*host1_resp_body, 3),
11813a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 4),
11814a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
11815a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11816a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<OrderedSocketData> spdy1_data(
11817a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      new OrderedSocketData(
11818a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          spdy1_reads, arraysize(spdy1_reads),
11819a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          spdy1_writes, arraysize(spdy1_writes)));
11820a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
11821a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
1182290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
11823a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      "https://www.b.com", false, 1, DEFAULT_PRIORITY));
11824a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockWrite spdy2_writes[] = {
11825a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockWrite(*host2_req, 1),
11826a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
118277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp(
118287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
118297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  scoped_ptr<SpdyFrame> host2_resp_body(
118307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      spdy_util_.ConstructSpdyBodyFrame(1, true));
11831a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockRead spdy2_reads[] = {
11832a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockRead(*host2_resp, 2),
11833a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    CreateMockRead(*host2_resp_body, 3),
11834a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead(ASYNC, ERR_IO_PENDING, 4),
11835a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
11836a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11837a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<OrderedSocketData> spdy2_data(
11838a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      new OrderedSocketData(
11839a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          spdy2_reads, arraysize(spdy2_reads),
11840a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)          spdy2_writes, arraysize(spdy2_writes)));
11841a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
11842a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11843a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockWrite http_write[] = {
11844a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
11845a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)              "Host: www.a.com\r\n"
11846a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
11847a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
11848a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11849a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  MockRead http_read[] = {
11850a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
11851a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11852a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead("Content-Length: 6\r\n\r\n"),
11853a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    MockRead("hello!"),
11854a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  };
11855a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  StaticSocketDataProvider http_data(http_read, arraysize(http_read),
11856a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                     http_write, arraysize(http_write));
11857a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11858a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11859a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HostPortPair host_port_pair_a("www.a.com", 443);
1186090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey spdy_session_key_a(
11861e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
11862a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
118637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11864a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11865a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  TestCompletionCallback callback;
11866a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HttpRequestInfo request1;
11867a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request1.method = "GET";
11868a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request1.url = GURL("https://www.a.com/");
11869a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request1.load_flags = 0;
11870a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  scoped_ptr<HttpNetworkTransaction> trans(
11871868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11872a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11873a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
11874a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11875a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
11876a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11877a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  const HttpResponseInfo* response = trans->GetResponseInfo();
11878a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
11879868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
11880a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11881a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
11882a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
11883a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11884a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  std::string response_data;
11885a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11886a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("hello!", response_data);
11887a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  trans.reset();
11888a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(
118897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11890a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11891a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HostPortPair host_port_pair_b("www.b.com", 443);
1189290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey spdy_session_key_b(
11893e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
11894a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
118957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11896a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HttpRequestInfo request2;
11897a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request2.method = "GET";
11898a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request2.url = GURL("https://www.b.com/");
11899a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request2.load_flags = 0;
11900868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11901a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11902a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  rv = trans->Start(&request2, callback.callback(), BoundNetLog());
11903a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11904a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
11905a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11906a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  response = trans->GetResponseInfo();
11907a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
11908868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
11909a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11910a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(response->was_fetched_via_spdy);
11911a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(response->was_npn_negotiated);
11912a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11913a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("hello!", response_data);
11914a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
119157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11916a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_TRUE(
119177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11918a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11919a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HostPortPair host_port_pair_a1("www.a.com", 80);
1192090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SpdySessionKey spdy_session_key_a1(
11921e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
11922a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
119237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
11924a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  HttpRequestInfo request3;
11925a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request3.method = "GET";
11926a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request3.url = GURL("http://www.a.com/");
11927a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  request3.load_flags = 0;
11928868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
11929a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11930a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  rv = trans->Start(&request3, callback.callback(), BoundNetLog());
11931a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING, rv);
11932a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ(OK, callback.WaitForResult());
11933a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11934a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  response = trans->GetResponseInfo();
11935a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_TRUE(response != NULL);
11936868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_TRUE(response->headers.get() != NULL);
11937a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11938a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(response->was_fetched_via_spdy);
11939a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(response->was_npn_negotiated);
11940a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11941a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_EQ("hello!", response_data);
11942a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
119437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
11944a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  EXPECT_FALSE(
119457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
11946a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
11947a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
11948eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
11949eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11950eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11951eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11952eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11953eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
119548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11955eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
119568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11957eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11958eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
11959eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data;
11960eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  data.set_connect_data(mock_connect);
11961eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
11962eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11963eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
11964eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11965eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11966eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
11967eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11968eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
11969eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
11970eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11971eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
11972eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11973eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // We don't care whether this succeeds or fails, but it shouldn't crash.
11974eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
11975eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  trans->GetFullRequestHeaders(&request_headers);
11976eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
11977eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11978eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
11979eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
11980eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
11981eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
11982eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
11983eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
119848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11985eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
119868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
11987eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11988eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11989eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data;
11990eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  data.set_connect_data(mock_connect);
11991eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
11992eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11993eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
11994eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11995eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
11996eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
11997eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
11998eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
11999eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12000eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12001eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
12002eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12003eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // We don't care whether this succeeds or fails, but it shouldn't crash.
12004eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
12005eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  trans->GetFullRequestHeaders(&request_headers);
12006eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
12007eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12008eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
12009eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
12010eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
12011eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
12012eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
12013eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
120148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12015eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
120168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12017eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12018eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
12019eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
12020eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12021eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
12022eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
12023eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12024eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12025eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12026eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
12027eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
12028eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12029eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
12030eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12031eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12032eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
12033eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12034eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
12035eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12036eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12037eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
12038eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12039eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
12040eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12041eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.HasHeader("Host"));
12042eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
12043eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12044eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
12045eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
12046eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
12047eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
12048eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
12049eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
120508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12051eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
120528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12053eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12054eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
12055eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite(ASYNC, ERR_CONNECTION_RESET),
12056eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12057eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
12058eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
12059eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12060eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12061eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12062eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
12063eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
12064eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12065eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
12066eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12067eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12068eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
12069eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12070eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
12071eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12072eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12073eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
12074eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12075eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
12076eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12077eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.HasHeader("Host"));
12078eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
12079eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12080eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
12081eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
12082eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
12083eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
12084eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
12085eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
120868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12087eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
120888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12089eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12090eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
12091eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite("GET / HTTP/1.1\r\n"
12092eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Host: www.google.com\r\n"
12093eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Connection: keep-alive\r\n\r\n"),
12094eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12095eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
12096eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
12097eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12098eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12099eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
12101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
12102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
12104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
12107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
12109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
12112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
12114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.HasHeader("Host"));
12116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
12117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
12119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
12120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
12121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
12122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
12123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
121248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
121268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
12129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite("GET / HTTP/1.1\r\n"
12130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Host: www.google.com\r\n"
12131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Connection: keep-alive\r\n\r\n"),
12132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
12134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(ASYNC, ERR_CONNECTION_RESET),
12135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
12139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
12140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
12142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
12145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
12147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
12148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(NULL, trans->GetResponseInfo());
12150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
12152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.HasHeader("Host"));
12154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
12155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochTEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
12157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestInfo request;
12158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.method = "GET";
12159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.url = GURL("http://www.google.com/");
12160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.load_flags = 0;
12161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  request.extra_headers.SetHeader("X-Foo", "bar");
12162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
121638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  scoped_ptr<HttpTransaction> trans(
121658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
12166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockWrite data_writes[] = {
12168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockWrite("GET / HTTP/1.1\r\n"
12169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Host: www.google.com\r\n"
12170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "Connection: keep-alive\r\n"
12171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch              "X-Foo: bar\r\n\r\n"),
12172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  MockRead data_reads[] = {
12174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead("HTTP/1.1 200 OK\r\n"
12175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch             "Content-Length: 5\r\n\r\n"
12176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch             "hello"),
12177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    MockRead(ASYNC, ERR_UNEXPECTED),
12178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
12179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                data_writes, arraysize(data_writes));
12182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
12183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  TestCompletionCallback callback;
12185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
12188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  rv = callback.WaitForResult();
12190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ(OK, rv);
12191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
12192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HttpRequestHeaders request_headers;
12193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
12194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::string foo;
12195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
12196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_EQ("bar", foo);
12197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
12198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
121993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace {
122003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Fake HttpStreamBase that simply records calls to SetPriority().
122023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class FakeStream : public HttpStreamBase,
122033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                   public base::SupportsWeakPtr<FakeStream> {
122043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
122053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  explicit FakeStream(RequestPriority priority) : priority_(priority) {}
122063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual ~FakeStream() {}
122073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RequestPriority priority() const { return priority_; }
122093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual int InitializeStream(const HttpRequestInfo* request_info,
122113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                               RequestPriority priority,
122123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                               const BoundNetLog& net_log,
122133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                               const CompletionCallback& callback) OVERRIDE {
122143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ERR_IO_PENDING;
122153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual int SendRequest(const HttpRequestHeaders& request_headers,
122183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          HttpResponseInfo* response,
122193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          const CompletionCallback& callback) OVERRIDE {
122203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ERR_UNEXPECTED;
122223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
122253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ERR_UNEXPECTED;
122273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
122303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                               const CompletionCallback& callback) OVERRIDE {
122313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ERR_UNEXPECTED;
122333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void Close(bool not_reusable) OVERRIDE {}
122363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool IsResponseBodyComplete() const OVERRIDE {
122383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
122403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool CanFindEndOfResponse() const OVERRIDE {
122433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
122443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool IsConnectionReused() const OVERRIDE {
122473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
122493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void SetConnectionReused() OVERRIDE {
122523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool IsConnectionReusable() const OVERRIDE {
122563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
122583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int64 GetTotalReceivedBytes() const OVERRIDE {
122615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ADD_FAILURE();
122625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return 0;
122635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
122645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
122653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool GetLoadTimingInfo(
122663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      LoadTimingInfo* load_timing_info) const OVERRIDE {
122673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
122693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
122723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void GetSSLCertRequestInfo(
122763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      SSLCertRequestInfo* cert_request_info) OVERRIDE {
122773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool IsSpdyHttpStream() const OVERRIDE {
122813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
122833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void Drain(HttpNetworkSession* session) OVERRIDE {
122863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
122873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void SetPriority(RequestPriority priority) OVERRIDE {
122903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    priority_ = priority;
122913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
122923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private:
122943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RequestPriority priority_;
122953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeStream);
122973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
122983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
122993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Fake HttpStreamRequest that simply records calls to SetPriority()
123003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// and vends FakeStreams with its current priority.
123013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class FakeStreamRequest : public HttpStreamRequest,
123023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                          public base::SupportsWeakPtr<FakeStreamRequest> {
123033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
123043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeStreamRequest(RequestPriority priority,
123053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                    HttpStreamRequest::Delegate* delegate)
123063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      : priority_(priority),
12307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        delegate_(delegate),
12308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        websocket_stream_create_helper_(NULL) {}
12309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  FakeStreamRequest(RequestPriority priority,
12311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    HttpStreamRequest::Delegate* delegate,
12312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                    WebSocketHandshakeStreamBase::CreateHelper* create_helper)
12313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : priority_(priority),
12314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        delegate_(delegate),
12315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        websocket_stream_create_helper_(create_helper) {}
123163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual ~FakeStreamRequest() {}
123183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RequestPriority priority() const { return priority_; }
123203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const WebSocketHandshakeStreamBase::CreateHelper*
12322f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  websocket_stream_create_helper() const {
12323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return websocket_stream_create_helper_;
12324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
12325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
123263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Create a new FakeStream and pass it to the request's
123273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // delegate. Returns a weak pointer to the FakeStream.
123283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStream> FinishStreamRequest() {
123293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FakeStream* fake_stream = new FakeStream(priority_);
123303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Do this before calling OnStreamReady() as OnStreamReady() may
123313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // immediately delete |fake_stream|.
123323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
123333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
123343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return weak_stream;
123353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual int RestartTunnelWithProxyAuth(
123383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const AuthCredentials& credentials) OVERRIDE {
123393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
123403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return ERR_UNEXPECTED;
123413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual LoadState GetLoadState() const OVERRIDE {
123443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
123453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return LoadState();
123463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void SetPriority(RequestPriority priority) OVERRIDE {
123493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    priority_ = priority;
123503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool was_npn_negotiated() const OVERRIDE {
123533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
123543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual NextProto protocol_negotiated() const OVERRIDE {
123573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return kProtoUnknown;
123583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool using_spdy() const OVERRIDE {
123613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
123623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private:
123653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  RequestPriority priority_;
123663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpStreamRequest::Delegate* const delegate_;
12367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
123683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
123703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
123713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Fake HttpStreamFactory that vends FakeStreamRequests.
123733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class FakeStreamFactory : public HttpStreamFactory {
123743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
123753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeStreamFactory() {}
123763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual ~FakeStreamFactory() {}
123773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Returns a WeakPtr<> to the last HttpStreamRequest returned by
123793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // RequestStream() (which may be NULL if it was destroyed already).
123803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStreamRequest> last_stream_request() {
123813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return last_stream_request_;
123823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual HttpStreamRequest* RequestStream(
123853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const HttpRequestInfo& info,
123863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      RequestPriority priority,
123873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const SSLConfig& server_ssl_config,
123883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const SSLConfig& proxy_ssl_config,
123893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpStreamRequest::Delegate* delegate,
123903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const BoundNetLog& net_log) OVERRIDE {
123913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
123923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    last_stream_request_ = fake_request->AsWeakPtr();
123933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return fake_request;
123943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
123953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
123961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
123973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const HttpRequestInfo& info,
123983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      RequestPriority priority,
123993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const SSLConfig& server_ssl_config,
124003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const SSLConfig& proxy_ssl_config,
124013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpStreamRequest::Delegate* delegate,
12402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      WebSocketHandshakeStreamBase::CreateHelper* create_helper,
124033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const BoundNetLog& net_log) OVERRIDE {
12404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FakeStreamRequest* fake_request =
12405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new FakeStreamRequest(priority, delegate, create_helper);
12406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    last_stream_request_ = fake_request->AsWeakPtr();
12407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return fake_request;
124083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
124093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual void PreconnectStreams(int num_streams,
124113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                 const HttpRequestInfo& info,
124123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                 RequestPriority priority,
124133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                 const SSLConfig& server_ssl_config,
124143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                 const SSLConfig& proxy_ssl_config) OVERRIDE {
124153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
124163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
124173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE {
124193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ADD_FAILURE();
124203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return NULL;
124213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
124223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) private:
124243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStreamRequest> last_stream_request_;
124253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
124273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
124283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// TODO(yhirano): Split this class out into a net/websockets file, if it is
12430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// worth doing.
12431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class FakeWebSocketStreamCreateHelper :
12432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      public WebSocketHandshakeStreamBase::CreateHelper {
12433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
12434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual WebSocketHandshakeStreamBase* CreateBasicStream(
12435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      scoped_ptr<ClientSocketHandle> connection,
12436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      bool using_proxy) OVERRIDE {
12437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NOTREACHED();
12438f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return NULL;
12439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
12440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12441f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual WebSocketHandshakeStreamBase* CreateSpdyStream(
12442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const base::WeakPtr<SpdySession>& session,
12443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      bool use_relative_url) OVERRIDE {
12444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NOTREACHED();
12445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return NULL;
12446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  };
12447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~FakeWebSocketStreamCreateHelper() {}
12449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12450f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual scoped_ptr<WebSocketStream> Upgrade() {
12451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NOTREACHED();
12452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return scoped_ptr<WebSocketStream>();
12453f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
12454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
12455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
124563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}  // namespace
124573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Make sure that HttpNetworkTransaction passes on its priority to its
124593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// stream request on start.
124603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
124613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
124623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkSessionPeer peer(session);
124633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeStreamFactory* fake_factory = new FakeStreamFactory();
12464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
124653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkTransaction trans(LOW, session);
124673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
124693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo request;
124713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback callback;
124723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
124733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            trans.Start(&request, callback.callback(), BoundNetLog()));
124743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStreamRequest> fake_request =
124763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      fake_factory->last_stream_request();
124773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_request != NULL);
124783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(LOW, fake_request->priority());
124793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
124803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Make sure that HttpNetworkTransaction passes on its priority
124823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// updates to its stream request.
124833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
124843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
124853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkSessionPeer peer(session);
124863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeStreamFactory* fake_factory = new FakeStreamFactory();
12487f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
124883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkTransaction trans(LOW, session);
124903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo request;
124923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback callback;
124933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
124943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            trans.Start(&request, callback.callback(), BoundNetLog()));
124953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
124963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStreamRequest> fake_request =
124973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      fake_factory->last_stream_request();
124983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_request != NULL);
124993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(LOW, fake_request->priority());
125003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  trans.SetPriority(LOWEST);
125023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_request != NULL);
125033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(LOWEST, fake_request->priority());
125043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
125053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Make sure that HttpNetworkTransaction passes on its priority
125073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// updates to its stream.
125083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
125093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
125103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkSessionPeer peer(session);
125113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeStreamFactory* fake_factory = new FakeStreamFactory();
12512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
125133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpNetworkTransaction trans(LOW, session);
125153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo request;
125173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback callback;
125183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
125193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            trans.Start(&request, callback.callback(), BoundNetLog()));
125203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStreamRequest> fake_request =
125223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      fake_factory->last_stream_request();
125233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_request != NULL);
125243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
125253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_TRUE(fake_stream != NULL);
125263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(LOW, fake_stream->priority());
125273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  trans.SetPriority(LOWEST);
125293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(LOWEST, fake_stream->priority());
125303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
125313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
12532f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
12533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // The same logic needs to be tested for both ws: and wss: schemes, but this
12534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // test is already parameterised on NextProto, so it uses a loop to verify
12535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // that the different schemes work.
12536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
12537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (size_t i = 0; i < arraysize(test_cases); ++i) {
12538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    HttpNetworkSessionPeer peer(session);
12540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FakeStreamFactory* fake_factory = new FakeStreamFactory();
12541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
12542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    peer.SetHttpStreamFactoryForWebSocket(
12543f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        scoped_ptr<HttpStreamFactory>(fake_factory));
12544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    HttpNetworkTransaction trans(LOW, session);
12546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    trans.SetWebSocketHandshakeStreamCreateHelper(
12547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        &websocket_stream_create_helper);
12548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    HttpRequestInfo request;
12550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    TestCompletionCallback callback;
12551f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    request.method = "GET";
12552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    request.url = GURL(test_cases[i]);
12553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(ERR_IO_PENDING,
12555f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              trans.Start(&request, callback.callback(), BoundNetLog()));
12556f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12557f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::WeakPtr<FakeStreamRequest> fake_request =
12558f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        fake_factory->last_stream_request();
12559f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(fake_request != NULL);
12560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(&websocket_stream_create_helper,
12561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              fake_request->websocket_stream_create_helper());
12562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
12563f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
12564f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
125653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Tests that when a used socket is returned to the SSL socket pool, it's closed
125663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// if the transport socket pool is stalled on the global socket limit.
125673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
125683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_group(
125693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
125703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_pool(
125713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
125723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Set up SSL request.
125743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo ssl_request;
125763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ssl_request.method = "GET";
125773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ssl_request.url = GURL("https://www.google.com/");
125783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockWrite ssl_writes[] = {
125803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
125813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Host: www.google.com\r\n"
125823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
125833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
125843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockRead ssl_reads[] = {
125853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
125863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("Content-Length: 11\r\n\r\n"),
125873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("hello world"),
125883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
125893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
125903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
125913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                    ssl_writes, arraysize(ssl_writes));
125923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
125933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
125953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
125963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Set up HTTP request.
125983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
125993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo http_request;
126003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  http_request.method = "GET";
126013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  http_request.url = GURL("http://www.google.com/");
126023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockWrite http_writes[] = {
126043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
126053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Host: www.google.com\r\n"
126063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
126073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
126083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockRead http_reads[] = {
126093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
126103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("Content-Length: 7\r\n\r\n"),
126113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("falafel"),
126123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
126133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
126143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
126153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     http_writes, arraysize(http_writes));
126163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&http_data);
126173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
126193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Start the SSL request.
126213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback ssl_callback;
126223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<HttpTransaction> ssl_trans(
126233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
126243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING,
126253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            ssl_trans->Start(&ssl_request, ssl_callback.callback(),
126263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            BoundNetLog()));
126273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Start the HTTP request.  Pool should stall.
126293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback http_callback;
126303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<HttpTransaction> http_trans(
126313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
126323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING,
126333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            http_trans->Start(&http_request, http_callback.callback(),
126343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                              BoundNetLog()));
126353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(IsTransportSocketPoolStalled(session));
126363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Wait for response from SSL request.
126383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, ssl_callback.WaitForResult());
126393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string response_data;
126403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
126413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ("hello world", response_data);
126423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // The SSL socket should automatically be closed, so the HTTP request can
126443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // start.
126453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
126463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_FALSE(IsTransportSocketPoolStalled(session));
126473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // The HTTP request can now complete.
126493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, http_callback.WaitForResult());
126503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
126513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ("falafel", response_data);
126523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
126543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
126553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Tests that when a SSL connection is established but there's no corresponding
126573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// request that needs it, the new socket is closed if the transport socket pool
126583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// is stalled on the global socket limit.
126593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
126603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_group(
126613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
126623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ClientSocketPoolManager::set_max_sockets_per_pool(
126633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
126643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Set up an ssl request.
126663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo ssl_request;
126683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ssl_request.method = "GET";
126693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ssl_request.url = GURL("https://www.foopy.com/");
126703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // No data will be sent on the SSL socket.
126723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StaticSocketDataProvider ssl_data;
126733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
126743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  SSLSocketDataProvider ssl(ASYNC, OK);
126763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
126773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Set up HTTP request.
126793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  HttpRequestInfo http_request;
126813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  http_request.method = "GET";
126823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  http_request.url = GURL("http://www.google.com/");
126833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockWrite http_writes[] = {
126853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockWrite("GET / HTTP/1.1\r\n"
126863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Host: www.google.com\r\n"
126873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)              "Connection: keep-alive\r\n\r\n"),
126883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
126893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MockRead http_reads[] = {
126903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("HTTP/1.1 200 OK\r\n"),
126913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("Content-Length: 7\r\n\r\n"),
126923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead("falafel"),
126933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    MockRead(SYNCHRONOUS, OK),
126943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  };
126953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
126963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                     http_writes, arraysize(http_writes));
126973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session_deps_.socket_factory->AddSocketDataProvider(&http_data);
126983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
126993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
127003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
127013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Preconnect an SSL socket.  A preconnect is needed because connect jobs are
127023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // cancelled when a normal transaction is cancelled.
127033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
127043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  net::SSLConfig ssl_config;
127053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  session->ssl_config_service()->GetSSLConfig(&ssl_config);
127063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
127073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                         ssl_config, ssl_config);
127083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
127093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
127103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Start the HTTP request.  Pool should stall.
127113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TestCompletionCallback http_callback;
127123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<HttpTransaction> http_trans(
127133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
127143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(ERR_IO_PENDING,
127153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            http_trans->Start(&http_request, http_callback.callback(),
127163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                              BoundNetLog()));
127173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_TRUE(IsTransportSocketPoolStalled(session));
127183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
127193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // The SSL connection will automatically be closed once the connection is
127203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // established, to let the HTTP request start.
127213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, http_callback.WaitForResult());
127223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string response_data;
127233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
127243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ("falafel", response_data);
127253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
127263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
127273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
127283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
127290529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
127300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
127310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
127320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
127330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
127350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
127360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
127370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
127380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
127390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
127410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
127420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
127430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
127440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
127450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
127460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
127470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
127480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
127490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
127500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
127510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
127530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
127540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("hello world"),
127550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
127560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
127570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
127580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
127590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
127600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
127620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
127640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
127650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
127670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
127680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
127700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_TRUE(response != NULL);
127710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response->headers.get() != NULL);
127730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
127740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string response_data;
127760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = ReadTransaction(trans.get(), &response_data);
127770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
127780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("hello world", response_data);
127790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
127800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// This test makes sure the retry logic doesn't trigger when reading an error
127820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// response from a server that rejected a POST with a CONNECTION_RESET.
127830529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest,
127840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       PostReadsErrorResponseAfterResetOnReusedSocket) {
127850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
127860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
127870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("GET / HTTP/1.1\r\n"
127880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
127890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n\r\n"),
127900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
127910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
127920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
127930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
127940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
127950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
127960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
127970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
127980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.1 200 Peachy\r\n"
127990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch             "Content-Length: 14\r\n\r\n"),
128000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("first response"),
128010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.1 400 Not OK\r\n"
128020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch             "Content-Length: 15\r\n\r\n"),
128030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("second response"),
128040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
128050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
128060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
128070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
128080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
128090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
128110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request1;
128120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request1.method = "GET";
128130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request1.url = GURL("http://www.foo.com/");
128140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request1.load_flags = 0;
128150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans1(
128170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
128180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
128190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
128200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
128220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
128230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response1 = trans1->GetResponseInfo();
128250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_TRUE(response1 != NULL);
128260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response1->headers.get() != NULL);
128280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
128290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string response_data1;
128310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = ReadTransaction(trans1.get(), &response_data1);
128320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
128330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("first response", response_data1);
128340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Delete the transaction to release the socket back into the socket pool.
128350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  trans1.reset();
128360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
128380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
128390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
128400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request2;
128420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request2.method = "POST";
128430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request2.url = GURL("http://www.foo.com/");
128440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request2.upload_data_stream = &upload_data_stream;
128450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request2.load_flags = 0;
128460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans2(
128480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
128490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
128500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
128510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
128530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
128540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response2 = trans2->GetResponseInfo();
128560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_TRUE(response2 != NULL);
128570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response2->headers.get() != NULL);
128590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
128600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string response_data2;
128620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = ReadTransaction(trans2.get(), &response_data2);
128630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
128640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("second response", response_data2);
128650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
128660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128670529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest,
128680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       PostReadsErrorResponseAfterResetPartialBodySent) {
128690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
128700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
128710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
128720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
128740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
128750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
128760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
128770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
128780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
128800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
128810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
128820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
128830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
128840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
128850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
128860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
128870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"
128880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "fo"),
128890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
128900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
128910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
128920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
128930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
128940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("hello world"),
128950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
128960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
128970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
128980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
128990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
129000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
129020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
129040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
129050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
129070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
129080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
129100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_TRUE(response != NULL);
129110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response->headers.get() != NULL);
129130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
129140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string response_data;
129160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = ReadTransaction(trans.get(), &response_data);
129170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
129180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("hello world", response_data);
129190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
129200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// This tests the more common case than the previous test, where headers and
129220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// body are not merged into a single request.
129230529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
129240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
129250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
129260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0);
129270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
129290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
129300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
129310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
129320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
129330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
129350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
129360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
129370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
129380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
129390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
129400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
129410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
129420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Transfer-Encoding: chunked\r\n\r\n"),
129430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
129440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
129450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
129470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
129480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("hello world"),
129490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
129500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
129510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
129520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
129530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
129540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
129560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
129580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
129590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Make sure the headers are sent before adding a chunk.  This ensures that
129600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // they can't be merged with the body in a single send.  Not currently
129610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // necessary since a chunked body is never merged with headers, but this makes
129620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // the test more future proof.
129630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::RunLoop().RunUntilIdle();
129640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  upload_data_stream.AppendChunk("last chunk", 10, true);
129660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
129680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
129690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
129710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_TRUE(response != NULL);
129720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response->headers.get() != NULL);
129740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
129750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string response_data;
129770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = ReadTransaction(trans.get(), &response_data);
129780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
129790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("hello world", response_data);
129800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
129810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129820529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
129830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
129840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
129850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
129860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
129880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
129890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
129900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
129910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
129920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
129940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
129950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
129960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
129970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
129980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
129990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
130000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
130010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
130020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
130030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
130040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
130060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
130070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
130080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("hello world"),
130090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
130100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
130110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
130120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
130130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
130140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
130160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
130180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
130190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
130210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
130220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
130240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ASSERT_TRUE(response != NULL);
130250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response->headers.get() != NULL);
130270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
130280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string response_data;
130300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = ReadTransaction(trans.get(), &response_data);
130310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(OK, rv);
130320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ("hello world", response_data);
130330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
130340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130350529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
130360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
130370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
130380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
130390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
130410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
130420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
130430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
130440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
130450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
130470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
130480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
130490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
130500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
130510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
130520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
130530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
130540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
130550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
130560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
130570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
130590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
130600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("hello world"),
130610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
130620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
130630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
130640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
130650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
130660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
130680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
130700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
130710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
130730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
130740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
130760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response == NULL);
130770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
130780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130790529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest,
130800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch       PostIgnoresNonErrorResponseAfterResetAnd100) {
130810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
130820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
130830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
130840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
130860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
130870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
130880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
130890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
130900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
130910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
130920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
130930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
130940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
130950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
130960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
130970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
130980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
130990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
131000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
131010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
131020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
131040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
131050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 302 Redirect\r\n"),
131060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("Location: http://somewhere-else.com/\r\n"),
131070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("Content-Length: 0\r\n\r\n"),
131080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
131090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
131100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
131110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
131120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
131130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
131150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
131170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
131180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
131200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
131210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
131230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response == NULL);
131240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
131250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131260529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
131270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
131280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
131290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
131300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
131320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
131330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
131340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
131350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
131360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
131380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
131390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
131400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
131410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
131420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
131430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
131440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
131450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
131460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
131470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
131480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
131500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP 0.9 rocks!"),
131510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
131520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
131530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
131540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
131550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
131560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
131580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
131600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
131610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
131630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
131640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
131660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response == NULL);
131670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
131680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131690529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
131700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ScopedVector<UploadElementReader> element_readers;
131710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  element_readers.push_back(new UploadBytesElementReader("foo", 3));
131720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  UploadDataStream upload_data_stream(element_readers.Pass(), 0);
131730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  HttpRequestInfo request;
131750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.method = "POST";
131760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.url = GURL("http://www.foo.com/");
131770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.upload_data_stream = &upload_data_stream;
131780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  request.load_flags = 0;
131790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
131810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<HttpTransaction> trans(
131820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
131830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Send headers successfully, but get an error while sending the body.
131840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockWrite data_writes[] = {
131850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite("POST / HTTP/1.1\r\n"
131860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Host: www.foo.com\r\n"
131870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Connection: keep-alive\r\n"
131880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch              "Content-Length: 3\r\n\r\n"),
131890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
131900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
131910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
131920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MockRead data_reads[] = {
131930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
131940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    MockRead(SYNCHRONOUS, OK),
131950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  };
131960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
131970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                arraysize(data_writes));
131980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  session_deps_.socket_factory->AddSocketDataProvider(&data);
131990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
132000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  TestCompletionCallback callback;
132010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
132020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int rv = trans->Start(&request, callback.callback(), BoundNetLog());
132030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_IO_PENDING, rv);
132040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
132050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rv = callback.WaitForResult();
132060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_EQ(ERR_CONNECTION_RESET, rv);
132070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
132080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const HttpResponseInfo* response = trans->GetResponseInfo();
132090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(response == NULL);
132100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
132110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
132125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
13213