blob: 14bda39448d3534d25d6c6b5e742fb08a47b8f07 [file] [log] [blame]
[email protected]23e482282013-06-14 16:08:021// Copyright 2013 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit586acc5fe2008-07-26 22:42:524
[email protected]2d731a32010-04-29 01:04:065#include "net/http/http_network_transaction.h"
6
[email protected]77848d12008-11-14 00:00:227#include <math.h> // ceil
[email protected]5285d972011-10-18 18:56:348#include <stdarg.h>
sclittlebe1ccf62015-09-02 19:40:369#include <stdint.h>
10
[email protected]5285d972011-10-18 18:56:3411#include <string>
[email protected]95d88ffe2010-02-04 21:25:3312#include <vector>
[email protected]77848d12008-11-14 00:00:2213
[email protected]2d731a32010-04-29 01:04:0614#include "base/basictypes.h"
[email protected]68bf9152008-09-25 19:47:3015#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5216#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2917#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5718#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2419#include "base/logging.h"
[email protected]3b63f8f42011-03-28 01:54:1520#include "base/memory/scoped_ptr.h"
[email protected]bf828982013-08-14 18:01:4721#include "base/memory/weak_ptr.h"
[email protected]a34f61ee2014-03-18 20:59:4922#include "base/run_loop.h"
bnc1b0e36852015-04-28 15:32:5923#include "base/stl_util.h"
[email protected]125ef482013-06-11 18:32:4724#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0525#include "base/strings/utf_string_conversions.h"
[email protected]f36a8132011-09-02 18:36:3326#include "base/test/test_file_util.h"
skyostil4891b25b2015-06-11 11:43:4527#include "base/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3528#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0729#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3330#include "net/base/completion_callback.h"
mmenkecbc2b712014-10-09 20:29:0731#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2532#include "net/base/load_timing_info.h"
33#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2434#include "net/base/net_errors.h"
[email protected]ac790b42009-12-02 04:31:3135#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5236#include "net/base/test_completion_callback.h"
[email protected]42fdb452012-11-01 12:44:4037#include "net/base/test_data_directory.h"
[email protected]b2d26cfd2012-12-11 10:36:0638#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2139#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1140#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1641#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5342#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2443#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1244#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0045#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2946#include "net/http/http_auth_handler_ntlm.h"
Adam Rice425cf122015-01-19 06:18:2447#include "net/http/http_basic_state.h"
[email protected]0877e3d2009-10-17 22:29:5748#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5249#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5650#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2451#include "net/http/http_request_headers.h"
[email protected]17291a022011-10-10 07:32:5352#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5753#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3854#include "net/http/http_stream_factory.h"
Adam Rice425cf122015-01-19 06:18:2455#include "net/http/http_stream_parser.h"
[email protected]c41737d2014-05-14 07:47:1956#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0757#include "net/log/net_log.h"
vishal.b62985ca92015-04-17 08:45:5158#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4659#include "net/log/test_net_log_entry.h"
60#include "net/log/test_net_log_util.h"
sammc5dd160c2015-04-02 02:43:1361#include "net/proxy/mock_proxy_resolver.h"
[email protected]51fff29d2008-12-19 22:17:5362#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0363#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1164#include "net/proxy/proxy_resolver.h"
65#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4466#include "net/socket/client_socket_factory.h"
[email protected]483fa202013-05-14 01:07:0367#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4768#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0269#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0770#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4471#include "net/socket/socket_test_util.h"
72#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5473#include "net/spdy/spdy_framer.h"
74#include "net/spdy/spdy_session.h"
75#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0276#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5777#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0378#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5779#include "net/ssl/ssl_config_service_defaults.h"
80#include "net/ssl/ssl_info.h"
[email protected]6e7845ae2013-03-29 21:48:1181#include "net/test/cert_test_util.h"
[email protected]831e4a32013-11-14 02:14:4482#include "net/websockets/websocket_handshake_stream_base.h"
initial.commit586acc5fe2008-07-26 22:42:5283#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1584#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:2785#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:5286
[email protected]ad65a3e2013-12-25 18:18:0187using base::ASCIIToUTF16;
88
initial.commit586acc5fe2008-07-26 22:42:5289//-----------------------------------------------------------------------------
90
ttuttle859dc7a2015-04-23 19:42:2991namespace net {
92
[email protected]13c8a092010-07-29 06:15:4493namespace {
94
[email protected]42cba2fb2013-03-29 19:58:5795const base::string16 kBar(ASCIIToUTF16("bar"));
96const base::string16 kBar2(ASCIIToUTF16("bar2"));
97const base::string16 kBar3(ASCIIToUTF16("bar3"));
98const base::string16 kBaz(ASCIIToUTF16("baz"));
99const base::string16 kFirst(ASCIIToUTF16("first"));
100const base::string16 kFoo(ASCIIToUTF16("foo"));
101const base::string16 kFoo2(ASCIIToUTF16("foo2"));
102const base::string16 kFoo3(ASCIIToUTF16("foo3"));
103const base::string16 kFou(ASCIIToUTF16("fou"));
104const base::string16 kSecond(ASCIIToUTF16("second"));
105const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
106const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44107
ttuttle859dc7a2015-04-23 19:42:29108int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
109 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
110 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02111}
112
ttuttle859dc7a2015-04-23 19:42:29113int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
114 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
115 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02116}
117
ttuttle859dc7a2015-04-23 19:42:29118bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
119 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
120 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52121}
122
[email protected]f3da152d2012-06-02 01:00:57123// Takes in a Value created from a NetLogHttpResponseParameter, and returns
124// a JSONified list of headers as a single string. Uses single quotes instead
125// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27126bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57127 if (!params)
128 return false;
[email protected]ea5ef4c2013-06-13 22:50:27129 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57130 if (!params->GetList("headers", &header_list))
131 return false;
132 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34133 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28134 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57135 return true;
136}
137
[email protected]029c83b62013-01-24 05:28:20138// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
139// used.
ttuttle859dc7a2015-04-23 19:42:29140void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20141 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29142 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25143
[email protected]029c83b62013-01-24 05:28:20144 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
145 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
146
ttuttle859dc7a2015-04-23 19:42:29147 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20148 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25149
150 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25151
[email protected]3b23a222013-05-15 21:33:25152 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25153 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
154 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25155 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25156}
157
[email protected]029c83b62013-01-24 05:28:20158// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
159// used.
ttuttle859dc7a2015-04-23 19:42:29160void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25161 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20162 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29163 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20164
165 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
166 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
167
ttuttle859dc7a2015-04-23 19:42:29168 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
169 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20170 EXPECT_LE(load_timing_info.connect_timing.connect_end,
171 load_timing_info.send_start);
172
173 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20174
[email protected]3b23a222013-05-15 21:33:25175 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20176 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
177 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25178 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20179}
180
181// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
182// used.
ttuttle859dc7a2015-04-23 19:42:29183void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20184 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29185 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20186
ttuttle859dc7a2015-04-23 19:42:29187 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20188
189 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
190 EXPECT_LE(load_timing_info.proxy_resolve_start,
191 load_timing_info.proxy_resolve_end);
192 EXPECT_LE(load_timing_info.proxy_resolve_end,
193 load_timing_info.send_start);
194 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20195
[email protected]3b23a222013-05-15 21:33:25196 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20197 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
198 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25199 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20200}
201
202// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
203// used.
ttuttle859dc7a2015-04-23 19:42:29204void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20205 int connect_timing_flags) {
206 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29207 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20208
209 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
210 EXPECT_LE(load_timing_info.proxy_resolve_start,
211 load_timing_info.proxy_resolve_end);
212 EXPECT_LE(load_timing_info.proxy_resolve_end,
213 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29214 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
215 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20216 EXPECT_LE(load_timing_info.connect_timing.connect_end,
217 load_timing_info.send_start);
218
219 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20220
[email protected]3b23a222013-05-15 21:33:25221 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20222 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
223 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25224 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25225}
226
ttuttle859dc7a2015-04-23 19:42:29227void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24228 headers->SetHeader("Connection", "Upgrade");
229 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23230 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24231 headers->SetHeader("Sec-WebSocket-Version", "13");
232 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
233}
234
[email protected]c6bf8152012-12-02 07:43:34235HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
236 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14237}
238
[email protected]448d4ca52012-03-04 04:12:23239} // namespace
240
[email protected]23e482282013-06-14 16:08:02241class HttpNetworkTransactionTest
242 : public PlatformTest,
243 public ::testing::WithParamInterface<NextProto> {
[email protected]483fa202013-05-14 01:07:03244 public:
[email protected]23e482282013-06-14 16:08:02245 virtual ~HttpNetworkTransactionTest() {
[email protected]483fa202013-05-14 01:07:03246 // Important to restore the per-pool limit first, since the pool limit must
247 // always be greater than group limit, and the tests reduce both limits.
248 ClientSocketPoolManager::set_max_sockets_per_pool(
249 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
250 ClientSocketPoolManager::set_max_sockets_per_group(
251 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
252 }
253
[email protected]e3ceb682011-06-28 23:55:46254 protected:
[email protected]23e482282013-06-14 16:08:02255 HttpNetworkTransactionTest()
256 : spdy_util_(GetParam()),
257 session_deps_(GetParam()),
[email protected]483fa202013-05-14 01:07:03258 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
259 HttpNetworkSession::NORMAL_SOCKET_POOL)),
260 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
261 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
262 }
[email protected]bb88e1d32013-05-03 23:11:07263
[email protected]e3ceb682011-06-28 23:55:46264 struct SimpleGetHelperResult {
265 int rv;
266 std::string status_line;
267 std::string response_data;
[email protected]b8015c42013-12-24 15:18:19268 int64 totalReceivedBytes;
[email protected]58e32bb2013-01-21 18:23:25269 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47270 ConnectionAttempts connection_attempts;
[email protected]e3ceb682011-06-28 23:55:46271 };
272
dcheng67be2b1f2014-10-27 21:47:29273 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50274 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34275 base::MessageLoop::current()->RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54276 }
277
dcheng67be2b1f2014-10-27 21:47:29278 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50279 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34280 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09281 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:34282 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09283 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50284 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
[email protected]2da659e2013-05-23 20:51:34285 base::MessageLoop::current()->RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09286 }
287
bnc33b8cef42014-11-19 17:30:38288 const char* GetAlternateProtocolFromParam() {
289 return
290 AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam()));
291 }
292
bncc958faa2015-07-31 18:14:52293 std::string GetAlternativeServiceHttpHeader() {
294 return std::string("Alt-Svc: ") + GetAlternateProtocolFromParam() +
295 "=\"www.example.com:443\"\r\n";
296 }
297
[email protected]8a0fc822013-06-27 20:52:43298 std::string GetAlternateProtocolHttpHeader() {
bnc33b8cef42014-11-19 17:30:38299 return std::string("Alternate-Protocol: 443:") +
bncc958faa2015-07-31 18:14:52300 GetAlternateProtocolFromParam() + "\r\n";
[email protected]8a0fc822013-06-27 20:52:43301 }
302
[email protected]202965992011-12-07 23:04:51303 // Either |write_failure| specifies a write failure or |read_failure|
304 // specifies a read failure when using a reused socket. In either case, the
305 // failure should cause the network transaction to resend the request, and the
306 // other argument should be NULL.
307 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
308 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52309
[email protected]a34f61ee2014-03-18 20:59:49310 // Either |write_failure| specifies a write failure or |read_failure|
311 // specifies a read failure when using a reused socket. In either case, the
312 // failure should cause the network transaction to resend the request, and the
313 // other argument should be NULL.
314 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10315 const MockRead* read_failure,
316 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49317
[email protected]5a60c8b2011-10-19 20:14:29318 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
319 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15320 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52321
[email protected]ff007e162009-05-23 09:13:15322 HttpRequestInfo request;
323 request.method = "GET";
bncce36dca22015-04-21 22:11:23324 request.url = GURL("http://www.example.org/");
[email protected]ff007e162009-05-23 09:13:15325 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52326
vishal.b62985ca92015-04-17 08:45:51327 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07328 session_deps_.net_log = log.bound().net_log();
[email protected]3fe8d2f82013-10-17 08:56:07329 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:27330 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41331 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27332
[email protected]5a60c8b2011-10-19 20:14:29333 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07334 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29335 }
initial.commit586acc5fe2008-07-26 22:42:52336
[email protected]49639fa2011-12-20 23:22:41337 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52338
eroman24bc6a12015-05-06 19:55:48339 EXPECT_TRUE(log.bound().IsCapturing());
[email protected]49639fa2011-12-20 23:22:41340 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15341 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52342
[email protected]ff007e162009-05-23 09:13:15343 out.rv = callback.WaitForResult();
[email protected]58e32bb2013-01-21 18:23:25344
345 // Even in the failure cases that use this function, connections are always
346 // successfully established before the error.
347 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
348 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
349
[email protected]ff007e162009-05-23 09:13:15350 if (out.rv != OK)
351 return out;
352
353 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50354 // Can't use ASSERT_* inside helper functions like this, so
355 // return an error.
[email protected]90499482013-06-01 00:39:50356 if (response == NULL || response->headers.get() == NULL) {
[email protected]fe2255a2011-09-20 19:37:50357 out.rv = ERR_UNEXPECTED;
358 return out;
359 }
[email protected]ff007e162009-05-23 09:13:15360 out.status_line = response->headers->GetStatusLine();
361
[email protected]80a09a82012-11-16 17:40:06362 EXPECT_EQ("127.0.0.1", response->socket_address.host());
363 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19364
[email protected]ff007e162009-05-23 09:13:15365 rv = ReadTransaction(trans.get(), &out.response_data);
366 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40367
mmenke43758e62015-05-04 21:09:46368 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40369 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39370 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40371 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12372 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39373 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40374 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39375 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
376 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15377
[email protected]f3da152d2012-06-02 01:00:57378 std::string line;
379 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
380 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
381
[email protected]79e1fd62013-06-20 06:50:04382 HttpRequestHeaders request_headers;
383 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
384 std::string value;
385 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23386 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04387 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
388 EXPECT_EQ("keep-alive", value);
389
390 std::string response_headers;
391 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23392 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04393 response_headers);
[email protected]3deb9a52010-11-11 00:24:40394
[email protected]b8015c42013-12-24 15:18:19395 out.totalReceivedBytes = trans->GetTotalReceivedBytes();
ttuttle1f2d7e92015-04-28 16:17:47396 trans->GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47397 return out;
[email protected]ff007e162009-05-23 09:13:15398 }
initial.commit586acc5fe2008-07-26 22:42:52399
[email protected]5a60c8b2011-10-19 20:14:29400 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
401 size_t reads_count) {
402 StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
403 StaticSocketDataProvider* data[] = { &reads };
404 return SimpleGetHelperForData(data, 1);
405 }
406
[email protected]b8015c42013-12-24 15:18:19407 int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
408 int64 size = 0;
409 for (size_t i = 0; i < reads_count; ++i)
410 size += data_reads[i].data_len;
411 return size;
412 }
413
[email protected]ff007e162009-05-23 09:13:15414 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
415 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52416
[email protected]ff007e162009-05-23 09:13:15417 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07418
419 void BypassHostCacheOnRefreshHelper(int load_flags);
420
421 void CheckErrorIsPassedBack(int error, IoMode mode);
422
[email protected]4bd46222013-05-14 19:32:23423 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07424 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03425
426 // Original socket limits. Some tests set these. Safest to always restore
427 // them once each test has been run.
428 int old_max_group_sockets_;
429 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15430};
[email protected]231d5a32008-09-13 00:45:27431
bnc57685ae62015-03-10 21:27:20432INSTANTIATE_TEST_CASE_P(NextProto,
433 HttpNetworkTransactionTest,
434 testing::Values(kProtoSPDY31,
bnc06d22432015-06-29 12:39:43435 kProtoHTTP2));
[email protected]23e482282013-06-14 16:08:02436
[email protected]448d4ca52012-03-04 04:12:23437namespace {
438
[email protected]1826a402014-01-08 15:40:48439class BeforeNetworkStartHandler {
440 public:
441 explicit BeforeNetworkStartHandler(bool defer)
442 : defer_on_before_network_start_(defer),
443 observed_before_network_start_(false) {}
444
445 void OnBeforeNetworkStart(bool* defer) {
446 *defer = defer_on_before_network_start_;
447 observed_before_network_start_ = true;
448 }
449
450 bool observed_before_network_start() const {
451 return observed_before_network_start_;
452 }
453
454 private:
455 const bool defer_on_before_network_start_;
456 bool observed_before_network_start_;
457
458 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
459};
460
[email protected]597a1ab2014-06-26 08:12:27461class BeforeProxyHeadersSentHandler {
462 public:
463 BeforeProxyHeadersSentHandler()
464 : observed_before_proxy_headers_sent_(false) {}
465
[email protected]1252d42f2014-07-01 21:20:20466 void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
467 HttpRequestHeaders* request_headers) {
[email protected]597a1ab2014-06-26 08:12:27468 observed_before_proxy_headers_sent_ = true;
469 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
470 }
471
472 bool observed_before_proxy_headers_sent() const {
473 return observed_before_proxy_headers_sent_;
474 }
475
476 std::string observed_proxy_server_uri() const {
477 return observed_proxy_server_uri_;
478 }
479
480 private:
481 bool observed_before_proxy_headers_sent_;
482 std::string observed_proxy_server_uri_;
483
484 DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler);
485};
486
[email protected]15a5ccf82008-10-23 19:57:43487// Fill |str| with a long header list that consumes >= |size| bytes.
488void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51489 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19490 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
491 const int sizeof_row = strlen(row);
492 const int num_rows = static_cast<int>(
493 ceil(static_cast<float>(size) / sizeof_row));
494 const int sizeof_data = num_rows * sizeof_row;
495 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43496 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51497
[email protected]4ddaf2502008-10-23 18:26:19498 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43499 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19500}
501
thakis84dff942015-07-28 20:47:38502#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29503// Alternative functions that eliminate randomness and dependency on the local
504// host name so that the generated NTLM messages are reproducible.
[email protected]fe2bc6a2009-03-23 16:52:20505void MockGenerateRandom1(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29506 static const uint8 bytes[] = {
507 0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
508 };
509 static size_t current_byte = 0;
510 for (size_t i = 0; i < n; ++i) {
511 output[i] = bytes[current_byte++];
512 current_byte %= arraysize(bytes);
513 }
514}
515
[email protected]fe2bc6a2009-03-23 16:52:20516void MockGenerateRandom2(uint8* output, size_t n) {
[email protected]385a4672009-03-11 22:21:29517 static const uint8 bytes[] = {
518 0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
519 0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
520 };
521 static size_t current_byte = 0;
522 for (size_t i = 0; i < n; ++i) {
523 output[i] = bytes[current_byte++];
524 current_byte %= arraysize(bytes);
525 }
526}
527
[email protected]fe2bc6a2009-03-23 16:52:20528std::string MockGetHostName() {
529 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29530}
thakis84dff942015-07-28 20:47:38531#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29532
[email protected]e60e47a2010-07-14 03:37:18533template<typename ParentPool>
534class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31535 public:
[email protected]9e1bdd32011-02-03 21:48:34536 CaptureGroupNameSocketPool(HostResolver* host_resolver,
537 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18538
[email protected]d80a4322009-08-14 07:07:49539 const std::string last_group_name_received() const {
540 return last_group_name_;
541 }
542
dmichaeld6e570d2014-12-18 22:30:57543 int RequestSocket(const std::string& group_name,
544 const void* socket_params,
545 RequestPriority priority,
546 ClientSocketHandle* handle,
547 const CompletionCallback& callback,
548 const BoundNetLog& net_log) override {
[email protected]04e5be32009-06-26 20:00:31549 last_group_name_ = group_name;
550 return ERR_IO_PENDING;
551 }
dmichaeld6e570d2014-12-18 22:30:57552 void CancelRequest(const std::string& group_name,
553 ClientSocketHandle* handle) override {}
554 void ReleaseSocket(const std::string& group_name,
555 scoped_ptr<StreamSocket> socket,
556 int id) override {}
557 void CloseIdleSockets() override {}
558 int IdleSocketCount() const override { return 0; }
559 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31560 return 0;
561 }
dmichaeld6e570d2014-12-18 22:30:57562 LoadState GetLoadState(const std::string& group_name,
563 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31564 return LOAD_STATE_IDLE;
565 }
dmichaeld6e570d2014-12-18 22:30:57566 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26567 return base::TimeDelta();
568 }
[email protected]d80a4322009-08-14 07:07:49569
570 private:
[email protected]04e5be32009-06-26 20:00:31571 std::string last_group_name_;
572};
573
[email protected]ab739042011-04-07 15:22:28574typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
575CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13576typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
577CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06578typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11579CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18580typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
581CaptureGroupNameSSLSocketPool;
582
rkaplowd90695c2015-03-25 22:12:41583template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18584CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34585 HostResolver* host_resolver,
586 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41587 : ParentPool(0, 0, host_resolver, NULL, NULL) {
588}
[email protected]e60e47a2010-07-14 03:37:18589
hashimoto0d3e4fb2015-01-09 05:02:50590template <>
[email protected]2df19bb2010-08-25 20:13:46591CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21592 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34593 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41594 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50595}
[email protected]2df19bb2010-08-25 20:13:46596
[email protected]007b3f82013-04-09 08:46:45597template <>
[email protected]e60e47a2010-07-14 03:37:18598CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21599 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34600 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45601 : SSLClientSocketPool(0,
602 0,
[email protected]007b3f82013-04-09 08:46:45603 cert_verifier,
604 NULL,
605 NULL,
[email protected]284303b62013-11-28 15:11:54606 NULL,
eranm6571b2b2014-12-03 15:53:23607 NULL,
[email protected]007b3f82013-04-09 08:46:45608 std::string(),
609 NULL,
610 NULL,
611 NULL,
612 NULL,
613 NULL,
[email protected]8e458552014-08-05 00:02:15614 NULL) {
615}
[email protected]2227c692010-05-04 15:36:11616
[email protected]231d5a32008-09-13 00:45:27617//-----------------------------------------------------------------------------
618
[email protected]79cb5c12011-09-12 13:12:04619// Helper functions for validating that AuthChallengeInfo's are correctly
620// configured for common cases.
621bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
622 if (!auth_challenge)
623 return false;
624 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23625 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04626 EXPECT_EQ("MyRealm1", auth_challenge->realm);
627 EXPECT_EQ("basic", auth_challenge->scheme);
628 return true;
629}
630
631bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
632 if (!auth_challenge)
633 return false;
634 EXPECT_TRUE(auth_challenge->is_proxy);
635 EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
636 EXPECT_EQ("MyRealm1", auth_challenge->realm);
637 EXPECT_EQ("basic", auth_challenge->scheme);
638 return true;
639}
640
641bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
642 if (!auth_challenge)
643 return false;
644 EXPECT_FALSE(auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:23645 EXPECT_EQ("www.example.org:80", auth_challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:04646 EXPECT_EQ("digestive", auth_challenge->realm);
647 EXPECT_EQ("digest", auth_challenge->scheme);
648 return true;
649}
650
thakis84dff942015-07-28 20:47:38651#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04652bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
653 if (!auth_challenge)
654 return false;
655 EXPECT_FALSE(auth_challenge->is_proxy);
656 EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
657 EXPECT_EQ(std::string(), auth_challenge->realm);
658 EXPECT_EQ("ntlm", auth_challenge->scheme);
659 return true;
660}
thakis84dff942015-07-28 20:47:38661#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04662
[email protected]448d4ca52012-03-04 04:12:23663} // namespace
664
[email protected]23e482282013-06-14 16:08:02665TEST_P(HttpNetworkTransactionTest, Basic) {
[email protected]3fe8d2f82013-10-17 08:56:07666 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:40667 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41668 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]231d5a32008-09-13 00:45:27669}
670
[email protected]23e482282013-06-14 16:08:02671TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27672 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35673 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
674 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06675 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27676 };
[email protected]31a2bfe2010-02-09 08:03:39677 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
678 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42679 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27680 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
681 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19682 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
683 EXPECT_EQ(reads_size, out.totalReceivedBytes);
ttuttle1f2d7e92015-04-28 16:17:47684 EXPECT_EQ(0u, out.connection_attempts.size());
[email protected]231d5a32008-09-13 00:45:27685}
686
687// Response with no status line.
[email protected]23e482282013-06-14 16:08:02688TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27689 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35690 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06691 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27692 };
[email protected]31a2bfe2010-02-09 08:03:39693 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
694 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42695 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27696 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
697 EXPECT_EQ("hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19698 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
699 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27700}
701
702// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02703TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27704 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35705 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06706 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27707 };
[email protected]31a2bfe2010-02-09 08:03:39708 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
709 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42710 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27711 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
712 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19713 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
714 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27715}
716
717// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02718TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27719 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35720 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06721 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27722 };
[email protected]31a2bfe2010-02-09 08:03:39723 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
724 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42725 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27726 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
727 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19728 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
729 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27730}
731
732// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02733TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27734 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35735 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06736 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27737 };
[email protected]31a2bfe2010-02-09 08:03:39738 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
739 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42740 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25741 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
742 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
[email protected]b8015c42013-12-24 15:18:19743 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
744 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27745}
746
747// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02748TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27749 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35750 MockRead("\n"),
751 MockRead("\n"),
752 MockRead("Q"),
753 MockRead("J"),
754 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06755 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27756 };
[email protected]31a2bfe2010-02-09 08:03:39757 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
758 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42759 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27760 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
761 EXPECT_EQ("DATA", out.response_data);
[email protected]b8015c42013-12-24 15:18:19762 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
763 EXPECT_EQ(reads_size, out.totalReceivedBytes);
[email protected]231d5a32008-09-13 00:45:27764}
765
766// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02767TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27768 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35769 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06770 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27771 };
[email protected]31a2bfe2010-02-09 08:03:39772 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
773 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42774 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27775 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
776 EXPECT_EQ("HTT", out.response_data);
[email protected]b8015c42013-12-24 15:18:19777 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
778 EXPECT_EQ(reads_size, out.totalReceivedBytes);
initial.commit586acc5fe2008-07-26 22:42:52779}
780
[email protected]f9d44aa2008-09-23 23:57:17781// Simulate a 204 response, lacking a Content-Length header, sent over a
782// persistent connection. The response should still terminate since a 204
783// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02784TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19785 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17786 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35787 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19788 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06789 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17790 };
[email protected]31a2bfe2010-02-09 08:03:39791 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
792 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42793 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17794 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
795 EXPECT_EQ("", out.response_data);
[email protected]b8015c42013-12-24 15:18:19796 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
797 int64 response_size = reads_size - strlen(junk);
798 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]f9d44aa2008-09-23 23:57:17799}
800
[email protected]0877e3d2009-10-17 22:29:57801// A simple request using chunked encoding with some extra data after.
[email protected]23e482282013-06-14 16:08:02802TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19803 std::string final_chunk = "0\r\n\r\n";
804 std::string extra_data = "HTTP/1.1 200 OK\r\n";
805 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57806 MockRead data_reads[] = {
807 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
808 MockRead("5\r\nHello\r\n"),
809 MockRead("1\r\n"),
810 MockRead(" \r\n"),
811 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19812 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06813 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57814 };
[email protected]31a2bfe2010-02-09 08:03:39815 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
816 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57817 EXPECT_EQ(OK, out.rv);
818 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
819 EXPECT_EQ("Hello world", out.response_data);
[email protected]b8015c42013-12-24 15:18:19820 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
821 int64 response_size = reads_size - extra_data.size();
822 EXPECT_EQ(response_size, out.totalReceivedBytes);
[email protected]0877e3d2009-10-17 22:29:57823}
824
[email protected]9fe44f52010-09-23 18:36:00825// Next tests deal with http://crbug.com/56344.
826
[email protected]23e482282013-06-14 16:08:02827TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00828 MultipleContentLengthHeadersNoTransferEncoding) {
829 MockRead data_reads[] = {
830 MockRead("HTTP/1.1 200 OK\r\n"),
831 MockRead("Content-Length: 10\r\n"),
832 MockRead("Content-Length: 5\r\n\r\n"),
833 };
834 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
835 arraysize(data_reads));
836 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
837}
838
[email protected]23e482282013-06-14 16:08:02839TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04840 DuplicateContentLengthHeadersNoTransferEncoding) {
841 MockRead data_reads[] = {
842 MockRead("HTTP/1.1 200 OK\r\n"),
843 MockRead("Content-Length: 5\r\n"),
844 MockRead("Content-Length: 5\r\n\r\n"),
845 MockRead("Hello"),
846 };
847 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
848 arraysize(data_reads));
849 EXPECT_EQ(OK, out.rv);
850 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
851 EXPECT_EQ("Hello", out.response_data);
852}
853
[email protected]23e482282013-06-14 16:08:02854TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04855 ComplexContentLengthHeadersNoTransferEncoding) {
856 // More than 2 dupes.
857 {
858 MockRead data_reads[] = {
859 MockRead("HTTP/1.1 200 OK\r\n"),
860 MockRead("Content-Length: 5\r\n"),
861 MockRead("Content-Length: 5\r\n"),
862 MockRead("Content-Length: 5\r\n\r\n"),
863 MockRead("Hello"),
864 };
865 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
866 arraysize(data_reads));
867 EXPECT_EQ(OK, out.rv);
868 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
869 EXPECT_EQ("Hello", out.response_data);
870 }
871 // HTTP/1.0
872 {
873 MockRead data_reads[] = {
874 MockRead("HTTP/1.0 200 OK\r\n"),
875 MockRead("Content-Length: 5\r\n"),
876 MockRead("Content-Length: 5\r\n"),
877 MockRead("Content-Length: 5\r\n\r\n"),
878 MockRead("Hello"),
879 };
880 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
881 arraysize(data_reads));
882 EXPECT_EQ(OK, out.rv);
883 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
884 EXPECT_EQ("Hello", out.response_data);
885 }
886 // 2 dupes and one mismatched.
887 {
888 MockRead data_reads[] = {
889 MockRead("HTTP/1.1 200 OK\r\n"),
890 MockRead("Content-Length: 10\r\n"),
891 MockRead("Content-Length: 10\r\n"),
892 MockRead("Content-Length: 5\r\n\r\n"),
893 };
894 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
895 arraysize(data_reads));
896 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
897 }
898}
899
[email protected]23e482282013-06-14 16:08:02900TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00901 MultipleContentLengthHeadersTransferEncoding) {
902 MockRead data_reads[] = {
903 MockRead("HTTP/1.1 200 OK\r\n"),
904 MockRead("Content-Length: 666\r\n"),
905 MockRead("Content-Length: 1337\r\n"),
906 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
907 MockRead("5\r\nHello\r\n"),
908 MockRead("1\r\n"),
909 MockRead(" \r\n"),
910 MockRead("5\r\nworld\r\n"),
911 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06912 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00913 };
914 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
915 arraysize(data_reads));
916 EXPECT_EQ(OK, out.rv);
917 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
918 EXPECT_EQ("Hello world", out.response_data);
919}
920
[email protected]1628fe92011-10-04 23:04:55921// Next tests deal with http://crbug.com/98895.
922
923// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02924TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55925 MockRead data_reads[] = {
926 MockRead("HTTP/1.1 200 OK\r\n"),
927 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
928 MockRead("Content-Length: 5\r\n\r\n"),
929 MockRead("Hello"),
930 };
931 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
932 arraysize(data_reads));
933 EXPECT_EQ(OK, out.rv);
934 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
935 EXPECT_EQ("Hello", out.response_data);
936}
937
[email protected]54a9c6e52012-03-21 20:10:59938// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:02939TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:59940 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55941 MockRead data_reads[] = {
942 MockRead("HTTP/1.1 200 OK\r\n"),
943 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
944 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
945 MockRead("Content-Length: 5\r\n\r\n"),
946 MockRead("Hello"),
947 };
948 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
949 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:59950 EXPECT_EQ(OK, out.rv);
951 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
952 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:55953}
954
955// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:02956TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:55957 MockRead data_reads[] = {
958 MockRead("HTTP/1.1 200 OK\r\n"),
959 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
960 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
961 MockRead("Content-Length: 5\r\n\r\n"),
962 MockRead("Hello"),
963 };
964 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
965 arraysize(data_reads));
966 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
967}
968
[email protected]54a9c6e52012-03-21 20:10:59969// Checks that two identical Location headers result in no error.
970// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:02971TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:55972 MockRead data_reads[] = {
973 MockRead("HTTP/1.1 302 Redirect\r\n"),
974 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:59975 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:55976 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:06977 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:55978 };
979
980 HttpRequestInfo request;
981 request.method = "GET";
982 request.url = GURL("http://redirect.com/");
983 request.load_flags = 0;
984
[email protected]3fe8d2f82013-10-17 08:56:07985 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1628fe92011-10-04 23:04:55986 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41987 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]1628fe92011-10-04 23:04:55988
989 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:07990 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:55991
[email protected]49639fa2011-12-20 23:22:41992 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:55993
[email protected]49639fa2011-12-20 23:22:41994 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:55995 EXPECT_EQ(ERR_IO_PENDING, rv);
996
997 EXPECT_EQ(OK, callback.WaitForResult());
998
999 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]90499482013-06-01 00:39:501000 ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
[email protected]1628fe92011-10-04 23:04:551001 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1002 std::string url;
1003 EXPECT_TRUE(response->headers->IsRedirect(&url));
1004 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:151005 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:551006}
1007
[email protected]1628fe92011-10-04 23:04:551008// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:021009TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551010 MockRead data_reads[] = {
1011 MockRead("HTTP/1.1 302 Redirect\r\n"),
1012 MockRead("Location: http://good.com/\r\n"),
1013 MockRead("Location: http://evil.com/\r\n"),
1014 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061015 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551016 };
1017 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1018 arraysize(data_reads));
1019 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
1020}
1021
[email protected]ef0faf2e72009-03-05 23:27:231022// Do a request using the HEAD method. Verify that we don't try to read the
1023// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:021024TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421025 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231026 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231027 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231028 request.load_flags = 0;
1029
[email protected]3fe8d2f82013-10-17 08:56:071030 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271031 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411032 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:271033 BeforeProxyHeadersSentHandler proxy_headers_handler;
1034 trans->SetBeforeProxyHeadersSentCallback(
1035 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
1036 base::Unretained(&proxy_headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271037
[email protected]ef0faf2e72009-03-05 23:27:231038 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131039 MockWrite("HEAD / HTTP/1.1\r\n"
1040 "Host: www.example.org\r\n"
1041 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231042 };
1043 MockRead data_reads1[] = {
1044 MockRead("HTTP/1.1 404 Not Found\r\n"),
1045 MockRead("Server: Blah\r\n"),
1046 MockRead("Content-Length: 1234\r\n\r\n"),
1047
1048 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:061049 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]ef0faf2e72009-03-05 23:27:231050 };
1051
[email protected]31a2bfe2010-02-09 08:03:391052 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1053 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071054 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231055
[email protected]49639fa2011-12-20 23:22:411056 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231057
[email protected]49639fa2011-12-20 23:22:411058 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421059 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231060
1061 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421062 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231063
[email protected]1c773ea12009-04-28 19:58:421064 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501065 ASSERT_TRUE(response != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231066
1067 // Check that the headers got parsed.
[email protected]90499482013-06-01 00:39:501068 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]ef0faf2e72009-03-05 23:27:231069 EXPECT_EQ(1234, response->headers->GetContentLength());
1070 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151071 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]597a1ab2014-06-26 08:12:271072 EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
[email protected]ef0faf2e72009-03-05 23:27:231073
1074 std::string server_header;
1075 void* iter = NULL;
1076 bool has_server_header = response->headers->EnumerateHeader(
1077 &iter, "Server", &server_header);
1078 EXPECT_TRUE(has_server_header);
1079 EXPECT_EQ("Blah", server_header);
1080
1081 // Reading should give EOF right away, since there is no message body
1082 // (despite non-zero content-length).
1083 std::string response_data;
1084 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421085 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231086 EXPECT_EQ("", response_data);
1087}
1088
[email protected]23e482282013-06-14 16:08:021089TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
[email protected]bb88e1d32013-05-03 23:11:071090 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521091
1092 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351093 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1094 MockRead("hello"),
1095 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1096 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061097 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521098 };
[email protected]31a2bfe2010-02-09 08:03:391099 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071100 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521101
[email protected]0b0bf032010-09-21 18:08:501102 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521103 "hello", "world"
1104 };
1105
1106 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421107 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521108 request.method = "GET";
bncce36dca22015-04-21 22:11:231109 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521110 request.load_flags = 0;
1111
[email protected]262eec82013-03-19 21:01:361112 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501113 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271114
[email protected]49639fa2011-12-20 23:22:411115 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521116
[email protected]49639fa2011-12-20 23:22:411117 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421118 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521119
1120 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421121 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521122
[email protected]1c773ea12009-04-28 19:58:421123 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501124 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521125
[email protected]90499482013-06-01 00:39:501126 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251127 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151128 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521129
1130 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571131 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421132 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251133 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521134 }
1135}
1136
[email protected]23e482282013-06-14 16:08:021137TEST_P(HttpNetworkTransactionTest, Ignores100) {
[email protected]b2d26cfd2012-12-11 10:36:061138 ScopedVector<UploadElementReader> element_readers;
1139 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:071140 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:271141
[email protected]1c773ea12009-04-28 19:58:421142 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521143 request.method = "POST";
1144 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271145 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521146 request.load_flags = 0;
1147
[email protected]3fe8d2f82013-10-17 08:56:071148 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271149 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411150 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271151
initial.commit586acc5fe2008-07-26 22:42:521152 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351153 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1154 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1155 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061156 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521157 };
[email protected]31a2bfe2010-02-09 08:03:391158 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071159 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521160
[email protected]49639fa2011-12-20 23:22:411161 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521162
[email protected]49639fa2011-12-20 23:22:411163 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421164 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521165
1166 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421167 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521168
[email protected]1c773ea12009-04-28 19:58:421169 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501170 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521171
[email protected]90499482013-06-01 00:39:501172 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251173 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521174
1175 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571176 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421177 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251178 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521179}
1180
[email protected]3a2d3662009-03-27 03:49:141181// This test is almost the same as Ignores100 above, but the response contains
1182// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571183// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021184TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421185 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141186 request.method = "GET";
1187 request.url = GURL("http://www.foo.com/");
1188 request.load_flags = 0;
1189
[email protected]3fe8d2f82013-10-17 08:56:071190 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271191 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411192 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271193
[email protected]3a2d3662009-03-27 03:49:141194 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571195 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1196 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141197 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061198 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141199 };
[email protected]31a2bfe2010-02-09 08:03:391200 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071201 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141202
[email protected]49639fa2011-12-20 23:22:411203 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141204
[email protected]49639fa2011-12-20 23:22:411205 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421206 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141207
1208 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421209 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141210
[email protected]1c773ea12009-04-28 19:58:421211 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501212 ASSERT_TRUE(response != NULL);
[email protected]3a2d3662009-03-27 03:49:141213
[email protected]90499482013-06-01 00:39:501214 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3a2d3662009-03-27 03:49:141215 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1216
1217 std::string response_data;
1218 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421219 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141220 EXPECT_EQ("hello world", response_data);
1221}
1222
[email protected]23e482282013-06-14 16:08:021223TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081224 HttpRequestInfo request;
1225 request.method = "POST";
1226 request.url = GURL("http://www.foo.com/");
1227 request.load_flags = 0;
1228
1229 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1230 scoped_ptr<HttpTransaction> trans(
1231 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1232
1233 MockRead data_reads[] = {
1234 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1235 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381236 };
zmo9528c9f42015-08-04 22:12:081237 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1238 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381239
zmo9528c9f42015-08-04 22:12:081240 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381241
zmo9528c9f42015-08-04 22:12:081242 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1243 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ee9410e72010-01-07 01:42:381244
zmo9528c9f42015-08-04 22:12:081245 rv = callback.WaitForResult();
1246 EXPECT_EQ(OK, rv);
[email protected]ee9410e72010-01-07 01:42:381247
zmo9528c9f42015-08-04 22:12:081248 std::string response_data;
1249 rv = ReadTransaction(trans.get(), &response_data);
1250 EXPECT_EQ(OK, rv);
1251 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381252}
1253
[email protected]23e482282013-06-14 16:08:021254TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381255 HttpRequestInfo request;
1256 request.method = "POST";
1257 request.url = GURL("http://www.foo.com/");
1258 request.load_flags = 0;
1259
[email protected]3fe8d2f82013-10-17 08:56:071260 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271261 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411262 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271263
[email protected]ee9410e72010-01-07 01:42:381264 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061265 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381266 };
[email protected]31a2bfe2010-02-09 08:03:391267 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071268 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381269
[email protected]49639fa2011-12-20 23:22:411270 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381271
[email protected]49639fa2011-12-20 23:22:411272 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381273 EXPECT_EQ(ERR_IO_PENDING, rv);
1274
1275 rv = callback.WaitForResult();
1276 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1277}
1278
[email protected]23e482282013-06-14 16:08:021279void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511280 const MockWrite* write_failure,
1281 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421282 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521283 request.method = "GET";
1284 request.url = GURL("http://www.foo.com/");
1285 request.load_flags = 0;
1286
vishal.b62985ca92015-04-17 08:45:511287 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071288 session_deps_.net_log = &net_log;
1289 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271290
[email protected]202965992011-12-07 23:04:511291 // Written data for successfully sending both requests.
1292 MockWrite data1_writes[] = {
1293 MockWrite("GET / HTTP/1.1\r\n"
1294 "Host: www.foo.com\r\n"
1295 "Connection: keep-alive\r\n\r\n"),
1296 MockWrite("GET / HTTP/1.1\r\n"
1297 "Host: www.foo.com\r\n"
1298 "Connection: keep-alive\r\n\r\n")
1299 };
1300
1301 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521302 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351303 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1304 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061305 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521306 };
[email protected]202965992011-12-07 23:04:511307
1308 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491309 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511310 data1_writes[1] = *write_failure;
1311 } else {
1312 ASSERT_TRUE(read_failure);
1313 data1_reads[2] = *read_failure;
1314 }
1315
1316 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1317 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071318 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521319
1320 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351321 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1322 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061323 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521324 };
[email protected]31a2bfe2010-02-09 08:03:391325 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071326 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521327
thestig9d3bb0c2015-01-24 00:49:511328 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521329 "hello", "world"
1330 };
1331
[email protected]58e32bb2013-01-21 18:23:251332 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521333 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411334 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521335
[email protected]262eec82013-03-19 21:01:361336 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501337 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521338
[email protected]49639fa2011-12-20 23:22:411339 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421340 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521341
1342 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421343 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521344
[email protected]58e32bb2013-01-21 18:23:251345 LoadTimingInfo load_timing_info;
1346 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1347 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1348 if (i == 0) {
1349 first_socket_log_id = load_timing_info.socket_log_id;
1350 } else {
1351 // The second request should be using a new socket.
1352 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1353 }
1354
[email protected]1c773ea12009-04-28 19:58:421355 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501356 ASSERT_TRUE(response != NULL);
initial.commit586acc5fe2008-07-26 22:42:521357
[email protected]90499482013-06-01 00:39:501358 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]3d2a59b2008-09-26 19:44:251359 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521360
1361 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571362 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421363 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251364 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521365 }
1366}
[email protected]3d2a59b2008-09-26 19:44:251367
[email protected]a34f61ee2014-03-18 20:59:491368void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1369 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101370 const MockRead* read_failure,
1371 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491372 HttpRequestInfo request;
1373 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101374 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491375 request.load_flags = 0;
1376
vishal.b62985ca92015-04-17 08:45:511377 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491378 session_deps_.net_log = &net_log;
1379 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1380
[email protected]09356c652014-03-25 15:36:101381 SSLSocketDataProvider ssl1(ASYNC, OK);
1382 SSLSocketDataProvider ssl2(ASYNC, OK);
1383 if (use_spdy) {
1384 ssl1.SetNextProto(GetParam());
1385 ssl2.SetNextProto(GetParam());
1386 }
1387 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1388 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491389
[email protected]09356c652014-03-25 15:36:101390 // SPDY versions of the request and response.
1391 scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
1392 request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
1393 scoped_ptr<SpdyFrame> spdy_response(
1394 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1395 scoped_ptr<SpdyFrame> spdy_data(
1396 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491397
[email protected]09356c652014-03-25 15:36:101398 // HTTP/1.1 versions of the request and response.
1399 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1400 "Host: www.foo.com\r\n"
1401 "Connection: keep-alive\r\n\r\n";
1402 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1403 const char kHttpData[] = "hello";
1404
1405 std::vector<MockRead> data1_reads;
1406 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491407 if (write_failure) {
1408 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101409 data1_writes.push_back(*write_failure);
1410 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491411 } else {
1412 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101413 if (use_spdy) {
1414 data1_writes.push_back(CreateMockWrite(*spdy_request));
1415 } else {
1416 data1_writes.push_back(MockWrite(kHttpRequest));
1417 }
1418 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491419 }
1420
[email protected]09356c652014-03-25 15:36:101421 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1422 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491423 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1424
[email protected]09356c652014-03-25 15:36:101425 std::vector<MockRead> data2_reads;
1426 std::vector<MockWrite> data2_writes;
1427
1428 if (use_spdy) {
1429 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1430
1431 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1432 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1433 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1434 } else {
1435 data2_writes.push_back(
1436 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1437
1438 data2_reads.push_back(
1439 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1440 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1441 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1442 }
rch8e6c6c42015-05-01 14:05:131443 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1444 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491445 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1446
1447 // Preconnect a socket.
ttuttle859dc7a2015-04-23 19:42:291448 SSLConfig ssl_config;
[email protected]a34f61ee2014-03-18 20:59:491449 session->ssl_config_service()->GetSSLConfig(&ssl_config);
[email protected]d7599122014-05-24 03:37:231450 session->GetNextProtos(&ssl_config.next_protos);
mmenked1205bd2015-07-15 22:26:351451 session->http_stream_factory()->PreconnectStreams(1, request, ssl_config,
1452 ssl_config);
[email protected]a34f61ee2014-03-18 20:59:491453 // Wait for the preconnect to complete.
1454 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1455 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101456 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491457
1458 // Make the request.
1459 TestCompletionCallback callback;
1460
1461 scoped_ptr<HttpTransaction> trans(
1462 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1463
1464 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1465 EXPECT_EQ(ERR_IO_PENDING, rv);
1466
1467 rv = callback.WaitForResult();
1468 EXPECT_EQ(OK, rv);
1469
1470 LoadTimingInfo load_timing_info;
1471 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101472 TestLoadTimingNotReused(
1473 load_timing_info,
1474 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491475
1476 const HttpResponseInfo* response = trans->GetResponseInfo();
1477 ASSERT_TRUE(response != NULL);
1478
1479 EXPECT_TRUE(response->headers.get() != NULL);
1480 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1481
1482 std::string response_data;
1483 rv = ReadTransaction(trans.get(), &response_data);
1484 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101485 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491486}
1487
[email protected]23e482282013-06-14 16:08:021488TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231489 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061490 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511491 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1492}
1493
[email protected]23e482282013-06-14 16:08:021494TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061495 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511496 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251497}
1498
[email protected]23e482282013-06-14 16:08:021499TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061500 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511501 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251502}
1503
[email protected]d58ceea82014-06-04 10:55:541504// Make sure that on a 408 response (Request Timeout), the request is retried,
1505// if the socket was a reused keep alive socket.
1506TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1507 MockRead read_failure(SYNCHRONOUS,
1508 "HTTP/1.1 408 Request Timeout\r\n"
1509 "Connection: Keep-Alive\r\n"
1510 "Content-Length: 6\r\n\r\n"
1511 "Pickle");
1512 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1513}
1514
[email protected]a34f61ee2014-03-18 20:59:491515TEST_P(HttpNetworkTransactionTest,
1516 PreconnectErrorNotConnectedOnWrite) {
1517 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101518 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491519}
1520
1521TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1522 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101523 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491524}
1525
1526TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1527 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101528 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1529}
1530
1531TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1532 MockRead read_failure(ASYNC, OK); // EOF
1533 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1534}
1535
[email protected]d58ceea82014-06-04 10:55:541536// Make sure that on a 408 response (Request Timeout), the request is retried,
1537// if the socket was a preconnected (UNUSED_IDLE) socket.
1538TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1539 MockRead read_failure(SYNCHRONOUS,
1540 "HTTP/1.1 408 Request Timeout\r\n"
1541 "Connection: Keep-Alive\r\n"
1542 "Content-Length: 6\r\n\r\n"
1543 "Pickle");
1544 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1545 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1546}
1547
[email protected]09356c652014-03-25 15:36:101548TEST_P(HttpNetworkTransactionTest,
1549 SpdyPreconnectErrorNotConnectedOnWrite) {
1550 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1551 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1552}
1553
1554TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1555 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1556 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1557}
1558
1559TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1560 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1561 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1562}
1563
1564TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1565 MockRead read_failure(ASYNC, OK); // EOF
1566 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491567}
1568
[email protected]23e482282013-06-14 16:08:021569TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421570 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251571 request.method = "GET";
bncce36dca22015-04-21 22:11:231572 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251573 request.load_flags = 0;
1574
[email protected]3fe8d2f82013-10-17 08:56:071575 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271576 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411577 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271578
[email protected]3d2a59b2008-09-26 19:44:251579 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061580 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351581 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1582 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061583 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251584 };
[email protected]31a2bfe2010-02-09 08:03:391585 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071586 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251587
[email protected]49639fa2011-12-20 23:22:411588 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251589
[email protected]49639fa2011-12-20 23:22:411590 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421591 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251592
1593 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421594 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]3d2a59b2008-09-26 19:44:251595}
1596
1597// What do various browsers do when the server closes a non-keepalive
1598// connection without sending any response header or body?
1599//
1600// IE7: error page
1601// Safari 3.1.2 (Windows): error page
1602// Firefox 3.0.1: blank page
1603// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421604// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1605// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021606TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251607 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061608 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351609 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1610 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061611 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251612 };
[email protected]31a2bfe2010-02-09 08:03:391613 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1614 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421615 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251616}
[email protected]038e9a32008-10-08 22:40:161617
[email protected]1826a402014-01-08 15:40:481618// Test that network access can be deferred and resumed.
1619TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1620 HttpRequestInfo request;
1621 request.method = "GET";
bncce36dca22015-04-21 22:11:231622 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481623 request.load_flags = 0;
1624
1625 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1626 scoped_ptr<HttpTransaction> trans(
1627 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1628
1629 // Defer on OnBeforeNetworkStart.
1630 BeforeNetworkStartHandler net_start_handler(true); // defer
1631 trans->SetBeforeNetworkStartCallback(
1632 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1633 base::Unretained(&net_start_handler)));
1634
1635 MockRead data_reads[] = {
1636 MockRead("HTTP/1.0 200 OK\r\n"),
1637 MockRead("Content-Length: 5\r\n\r\n"),
1638 MockRead("hello"),
1639 MockRead(SYNCHRONOUS, 0),
1640 };
1641 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1642 session_deps_.socket_factory->AddSocketDataProvider(&data);
1643
1644 TestCompletionCallback callback;
1645
1646 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1647 EXPECT_EQ(ERR_IO_PENDING, rv);
1648 base::MessageLoop::current()->RunUntilIdle();
1649
1650 // Should have deferred for network start.
1651 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1652 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481653
1654 trans->ResumeNetworkStart();
1655 rv = callback.WaitForResult();
1656 EXPECT_EQ(OK, rv);
1657 EXPECT_TRUE(trans->GetResponseInfo() != NULL);
1658
1659 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1660 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1661 if (rv == ERR_IO_PENDING)
1662 rv = callback.WaitForResult();
1663 EXPECT_EQ(5, rv);
1664 trans.reset();
1665}
1666
1667// Test that network use can be deferred and canceled.
1668TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1669 HttpRequestInfo request;
1670 request.method = "GET";
bncce36dca22015-04-21 22:11:231671 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481672 request.load_flags = 0;
1673
1674 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1675 scoped_ptr<HttpTransaction> trans(
1676 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1677
1678 // Defer on OnBeforeNetworkStart.
1679 BeforeNetworkStartHandler net_start_handler(true); // defer
1680 trans->SetBeforeNetworkStartCallback(
1681 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1682 base::Unretained(&net_start_handler)));
1683
1684 TestCompletionCallback callback;
1685
1686 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1687 EXPECT_EQ(ERR_IO_PENDING, rv);
1688 base::MessageLoop::current()->RunUntilIdle();
1689
1690 // Should have deferred for network start.
1691 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1692 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481693}
1694
[email protected]7a5378b2012-11-04 03:25:171695// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1696// tests. There was a bug causing HttpNetworkTransaction to hang in the
1697// destructor in such situations.
1698// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021699TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171700 HttpRequestInfo request;
1701 request.method = "GET";
bncce36dca22015-04-21 22:11:231702 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171703 request.load_flags = 0;
1704
[email protected]bb88e1d32013-05-03 23:11:071705 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361706 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501707 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171708
1709 MockRead data_reads[] = {
1710 MockRead("HTTP/1.0 200 OK\r\n"),
1711 MockRead("Connection: keep-alive\r\n"),
1712 MockRead("Content-Length: 100\r\n\r\n"),
1713 MockRead("hello"),
1714 MockRead(SYNCHRONOUS, 0),
1715 };
1716 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071717 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171718
1719 TestCompletionCallback callback;
1720
1721 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1722 EXPECT_EQ(ERR_IO_PENDING, rv);
1723
1724 rv = callback.WaitForResult();
1725 EXPECT_EQ(OK, rv);
1726
1727 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501728 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171729 if (rv == ERR_IO_PENDING)
1730 rv = callback.WaitForResult();
1731 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501732 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171733 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1734
1735 trans.reset();
[email protected]2da659e2013-05-23 20:51:341736 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171737 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1738}
1739
[email protected]23e482282013-06-14 16:08:021740TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171741 HttpRequestInfo request;
1742 request.method = "GET";
bncce36dca22015-04-21 22:11:231743 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171744 request.load_flags = 0;
1745
[email protected]bb88e1d32013-05-03 23:11:071746 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:361747 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501748 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171749
1750 MockRead data_reads[] = {
1751 MockRead("HTTP/1.0 200 OK\r\n"),
1752 MockRead("Connection: keep-alive\r\n"),
1753 MockRead("Content-Length: 100\r\n\r\n"),
1754 MockRead(SYNCHRONOUS, 0),
1755 };
1756 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071757 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171758
1759 TestCompletionCallback callback;
1760
1761 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1762 EXPECT_EQ(ERR_IO_PENDING, rv);
1763
1764 rv = callback.WaitForResult();
1765 EXPECT_EQ(OK, rv);
1766
1767 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501768 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171769 if (rv == ERR_IO_PENDING)
1770 rv = callback.WaitForResult();
1771 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1772
1773 trans.reset();
[email protected]2da659e2013-05-23 20:51:341774 base::MessageLoop::current()->RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171775 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1776}
1777
[email protected]0b0bf032010-09-21 18:08:501778// Test that we correctly reuse a keep-alive connection after not explicitly
1779// reading the body.
[email protected]23e482282013-06-14 16:08:021780TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131781 HttpRequestInfo request;
1782 request.method = "GET";
1783 request.url = GURL("http://www.foo.com/");
1784 request.load_flags = 0;
1785
vishal.b62985ca92015-04-17 08:45:511786 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071787 session_deps_.net_log = &net_log;
1788 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271789
[email protected]0b0bf032010-09-21 18:08:501790 // Note that because all these reads happen in the same
1791 // StaticSocketDataProvider, it shows that the same socket is being reused for
1792 // all transactions.
[email protected]fc31d6a42010-06-24 18:05:131793 MockRead data1_reads[] = {
[email protected]0b0bf032010-09-21 18:08:501794 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
1795 MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
[email protected]fc31d6a42010-06-24 18:05:131796 MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
[email protected]0b0bf032010-09-21 18:08:501797 MockRead("HTTP/1.1 302 Found\r\n"
1798 "Content-Length: 0\r\n\r\n"),
1799 MockRead("HTTP/1.1 302 Found\r\n"
1800 "Content-Length: 5\r\n\r\n"
1801 "hello"),
1802 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1803 "Content-Length: 0\r\n\r\n"),
1804 MockRead("HTTP/1.1 301 Moved Permanently\r\n"
1805 "Content-Length: 5\r\n\r\n"
1806 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131807 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1808 MockRead("hello"),
1809 };
1810 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071811 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]fc31d6a42010-06-24 18:05:131812
1813 MockRead data2_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061814 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]fc31d6a42010-06-24 18:05:131815 };
1816 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071817 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]fc31d6a42010-06-24 18:05:131818
[email protected]0b0bf032010-09-21 18:08:501819 const int kNumUnreadBodies = arraysize(data1_reads) - 2;
1820 std::string response_lines[kNumUnreadBodies];
1821
[email protected]58e32bb2013-01-21 18:23:251822 uint32 first_socket_log_id = NetLog::Source::kInvalidId;
[email protected]0b0bf032010-09-21 18:08:501823 for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411824 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131825
[email protected]262eec82013-03-19 21:01:361826 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501827 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131828
[email protected]49639fa2011-12-20 23:22:411829 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]fc31d6a42010-06-24 18:05:131830 EXPECT_EQ(ERR_IO_PENDING, rv);
1831
1832 rv = callback.WaitForResult();
1833 EXPECT_EQ(OK, rv);
1834
[email protected]58e32bb2013-01-21 18:23:251835 LoadTimingInfo load_timing_info;
1836 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1837 if (i == 0) {
1838 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1839 first_socket_log_id = load_timing_info.socket_log_id;
1840 } else {
1841 TestLoadTimingReused(load_timing_info);
1842 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1843 }
1844
[email protected]fc31d6a42010-06-24 18:05:131845 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]0b0bf032010-09-21 18:08:501846 ASSERT_TRUE(response != NULL);
[email protected]fc31d6a42010-06-24 18:05:131847
[email protected]90499482013-06-01 00:39:501848 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501849 response_lines[i] = response->headers->GetStatusLine();
1850
1851 // We intentionally don't read the response bodies.
[email protected]fc31d6a42010-06-24 18:05:131852 }
[email protected]0b0bf032010-09-21 18:08:501853
1854 const char* const kStatusLines[] = {
1855 "HTTP/1.1 204 No Content",
1856 "HTTP/1.1 205 Reset Content",
1857 "HTTP/1.1 304 Not Modified",
1858 "HTTP/1.1 302 Found",
1859 "HTTP/1.1 302 Found",
1860 "HTTP/1.1 301 Moved Permanently",
1861 "HTTP/1.1 301 Moved Permanently",
1862 };
1863
mostynb91e0da982015-01-20 19:17:271864 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1865 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501866
1867 for (int i = 0; i < kNumUnreadBodies; ++i)
1868 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1869
[email protected]49639fa2011-12-20 23:22:411870 TestCompletionCallback callback;
[email protected]262eec82013-03-19 21:01:361871 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501872 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411873 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0b0bf032010-09-21 18:08:501874 EXPECT_EQ(ERR_IO_PENDING, rv);
1875 rv = callback.WaitForResult();
1876 EXPECT_EQ(OK, rv);
1877 const HttpResponseInfo* response = trans->GetResponseInfo();
1878 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:501879 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]0b0bf032010-09-21 18:08:501880 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1881 std::string response_data;
1882 rv = ReadTransaction(trans.get(), &response_data);
1883 EXPECT_EQ(OK, rv);
1884 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131885}
1886
[email protected]038e9a32008-10-08 22:40:161887// Test the request-challenge-retry sequence for basic auth.
1888// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:021889TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:421890 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:161891 request.method = "GET";
bncce36dca22015-04-21 22:11:231892 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:161893 request.load_flags = 0;
1894
vishal.b62985ca92015-04-17 08:45:511895 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:071896 session_deps_.net_log = &log;
[email protected]3fe8d2f82013-10-17 08:56:071897 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271898 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411899 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271900
[email protected]f9ee6b52008-11-08 06:46:231901 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:231902 MockWrite(
1903 "GET / HTTP/1.1\r\n"
1904 "Host: www.example.org\r\n"
1905 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:231906 };
1907
[email protected]038e9a32008-10-08 22:40:161908 MockRead data_reads1[] = {
1909 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
1910 // Give a couple authenticate options (only the middle one is actually
1911 // supported).
[email protected]22927ad2009-09-21 19:56:191912 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:161913 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
1914 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
1915 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1916 // Large content-length -- won't matter, as connection will be reset.
1917 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061918 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:161919 };
1920
1921 // After calling trans->RestartWithAuth(), this is the request we should
1922 // be issuing -- the final header line contains the credentials.
1923 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:231924 MockWrite(
1925 "GET / HTTP/1.1\r\n"
1926 "Host: www.example.org\r\n"
1927 "Connection: keep-alive\r\n"
1928 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:161929 };
1930
1931 // Lastly, the server responds with the actual content.
1932 MockRead data_reads2[] = {
1933 MockRead("HTTP/1.0 200 OK\r\n"),
1934 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
1935 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061936 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:161937 };
1938
[email protected]31a2bfe2010-02-09 08:03:391939 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1940 data_writes1, arraysize(data_writes1));
1941 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
1942 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:071943 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1944 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:161945
[email protected]49639fa2011-12-20 23:22:411946 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:161947
[email protected]49639fa2011-12-20 23:22:411948 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421949 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161950
1951 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421952 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161953
[email protected]58e32bb2013-01-21 18:23:251954 LoadTimingInfo load_timing_info1;
1955 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
1956 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
1957
[email protected]b8015c42013-12-24 15:18:191958 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
1959 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
1960
[email protected]1c773ea12009-04-28 19:58:421961 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501962 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:041963 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:161964
[email protected]49639fa2011-12-20 23:22:411965 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:161966
[email protected]49639fa2011-12-20 23:22:411967 rv = trans->RestartWithAuth(
1968 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:421969 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:161970
1971 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421972 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:161973
[email protected]58e32bb2013-01-21 18:23:251974 LoadTimingInfo load_timing_info2;
1975 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
1976 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
1977 // The load timing after restart should have a new socket ID, and times after
1978 // those of the first load timing.
1979 EXPECT_LE(load_timing_info1.receive_headers_end,
1980 load_timing_info2.connect_timing.connect_start);
1981 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
1982
[email protected]b8015c42013-12-24 15:18:191983 int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
1984 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
1985
[email protected]038e9a32008-10-08 22:40:161986 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:501987 ASSERT_TRUE(response != NULL);
[email protected]038e9a32008-10-08 22:40:161988 EXPECT_TRUE(response->auth_challenge.get() == NULL);
1989 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:161990}
1991
[email protected]23e482282013-06-14 16:08:021992TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:461993 HttpRequestInfo request;
1994 request.method = "GET";
bncce36dca22015-04-21 22:11:231995 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:291996 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:461997
[email protected]3fe8d2f82013-10-17 08:56:071998 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271999 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412000 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272001
[email protected]861fcd52009-08-26 02:33:462002 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232003 MockWrite(
2004 "GET / HTTP/1.1\r\n"
2005 "Host: www.example.org\r\n"
2006 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462007 };
2008
2009 MockRead data_reads[] = {
2010 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2011 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2012 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2013 // Large content-length -- won't matter, as connection will be reset.
2014 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062015 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462016 };
2017
[email protected]31a2bfe2010-02-09 08:03:392018 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2019 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072020 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412021 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462022
[email protected]49639fa2011-12-20 23:22:412023 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462024 EXPECT_EQ(ERR_IO_PENDING, rv);
2025
2026 rv = callback.WaitForResult();
2027 EXPECT_EQ(0, rv);
2028
[email protected]b8015c42013-12-24 15:18:192029 int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
2030 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2031
[email protected]861fcd52009-08-26 02:33:462032 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502033 ASSERT_TRUE(response != NULL);
[email protected]861fcd52009-08-26 02:33:462034 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2035}
2036
[email protected]2d2697f92009-02-18 21:00:322037// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2038// connection.
[email protected]23e482282013-06-14 16:08:022039TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
[email protected]1c773ea12009-04-28 19:58:422040 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322041 request.method = "GET";
bncce36dca22015-04-21 22:11:232042 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322043 request.load_flags = 0;
2044
vishal.b62985ca92015-04-17 08:45:512045 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072046 session_deps_.net_log = &log;
2047 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272048
[email protected]2d2697f92009-02-18 21:00:322049 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232050 MockWrite(
2051 "GET / HTTP/1.1\r\n"
2052 "Host: www.example.org\r\n"
2053 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322054
bncce36dca22015-04-21 22:11:232055 // After calling trans->RestartWithAuth(), this is the request we should
2056 // be issuing -- the final header line contains the credentials.
2057 MockWrite(
2058 "GET / HTTP/1.1\r\n"
2059 "Host: www.example.org\r\n"
2060 "Connection: keep-alive\r\n"
2061 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322062 };
2063
2064 MockRead data_reads1[] = {
2065 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2066 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2067 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2068 MockRead("Content-Length: 14\r\n\r\n"),
2069 MockRead("Unauthorized\r\n"),
2070
2071 // Lastly, the server responds with the actual content.
2072 MockRead("HTTP/1.1 200 OK\r\n"),
2073 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502074 MockRead("Content-Length: 5\r\n\r\n"),
2075 MockRead("Hello"),
[email protected]2d2697f92009-02-18 21:00:322076 };
2077
[email protected]2d0a4f92011-05-05 16:38:462078 // If there is a regression where we disconnect a Keep-Alive
2079 // connection during an auth roundtrip, we'll end up reading this.
2080 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062081 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462082 };
2083
[email protected]31a2bfe2010-02-09 08:03:392084 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2085 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462086 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2087 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072088 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2089 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322090
[email protected]49639fa2011-12-20 23:22:412091 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322092
[email protected]262eec82013-03-19 21:01:362093 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502094 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412095 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422096 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322097
2098 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422099 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322100
[email protected]58e32bb2013-01-21 18:23:252101 LoadTimingInfo load_timing_info1;
2102 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2103 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2104
[email protected]1c773ea12009-04-28 19:58:422105 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502106 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042107 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322108
[email protected]49639fa2011-12-20 23:22:412109 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322110
[email protected]49639fa2011-12-20 23:22:412111 rv = trans->RestartWithAuth(
2112 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422113 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322114
2115 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422116 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322117
[email protected]58e32bb2013-01-21 18:23:252118 LoadTimingInfo load_timing_info2;
2119 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2120 TestLoadTimingReused(load_timing_info2);
2121 // The load timing after restart should have the same socket ID, and times
2122 // those of the first load timing.
2123 EXPECT_LE(load_timing_info1.receive_headers_end,
2124 load_timing_info2.send_start);
2125 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2126
[email protected]2d2697f92009-02-18 21:00:322127 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502128 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322129 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502130 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]b8015c42013-12-24 15:18:192131
2132 std::string response_data;
2133 rv = ReadTransaction(trans.get(), &response_data);
2134 EXPECT_EQ(OK, rv);
2135 int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
2136 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
[email protected]2d2697f92009-02-18 21:00:322137}
2138
2139// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2140// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022141TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422142 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322143 request.method = "GET";
bncce36dca22015-04-21 22:11:232144 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322145 request.load_flags = 0;
2146
[email protected]bb88e1d32013-05-03 23:11:072147 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272148
[email protected]2d2697f92009-02-18 21:00:322149 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232150 MockWrite(
2151 "GET / HTTP/1.1\r\n"
2152 "Host: www.example.org\r\n"
2153 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322154
bncce36dca22015-04-21 22:11:232155 // After calling trans->RestartWithAuth(), this is the request we should
2156 // be issuing -- the final header line contains the credentials.
2157 MockWrite(
2158 "GET / HTTP/1.1\r\n"
2159 "Host: www.example.org\r\n"
2160 "Connection: keep-alive\r\n"
2161 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322162 };
2163
[email protected]2d2697f92009-02-18 21:00:322164 MockRead data_reads1[] = {
2165 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2166 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312167 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322168
2169 // Lastly, the server responds with the actual content.
2170 MockRead("HTTP/1.1 200 OK\r\n"),
2171 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502172 MockRead("Content-Length: 5\r\n\r\n"),
2173 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322174 };
2175
[email protected]2d0a4f92011-05-05 16:38:462176 // An incorrect reconnect would cause this to be read.
2177 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062178 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462179 };
2180
[email protected]31a2bfe2010-02-09 08:03:392181 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2182 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462183 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2184 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072185 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2186 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322187
[email protected]49639fa2011-12-20 23:22:412188 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322189
[email protected]262eec82013-03-19 21:01:362190 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502191 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412192 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422193 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322194
2195 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422196 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322197
[email protected]1c773ea12009-04-28 19:58:422198 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502199 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042200 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322201
[email protected]49639fa2011-12-20 23:22:412202 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322203
[email protected]49639fa2011-12-20 23:22:412204 rv = trans->RestartWithAuth(
2205 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422206 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322207
2208 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422209 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322210
2211 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502212 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322213 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502214 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322215}
2216
2217// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2218// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022219TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422220 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322221 request.method = "GET";
bncce36dca22015-04-21 22:11:232222 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322223 request.load_flags = 0;
2224
[email protected]bb88e1d32013-05-03 23:11:072225 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272226
[email protected]2d2697f92009-02-18 21:00:322227 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232228 MockWrite(
2229 "GET / HTTP/1.1\r\n"
2230 "Host: www.example.org\r\n"
2231 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322232
bncce36dca22015-04-21 22:11:232233 // After calling trans->RestartWithAuth(), this is the request we should
2234 // be issuing -- the final header line contains the credentials.
2235 MockWrite(
2236 "GET / HTTP/1.1\r\n"
2237 "Host: www.example.org\r\n"
2238 "Connection: keep-alive\r\n"
2239 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322240 };
2241
2242 // Respond with 5 kb of response body.
2243 std::string large_body_string("Unauthorized");
2244 large_body_string.append(5 * 1024, ' ');
2245 large_body_string.append("\r\n");
2246
2247 MockRead data_reads1[] = {
2248 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2249 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2250 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2251 // 5134 = 12 + 5 * 1024 + 2
2252 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062253 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322254
2255 // Lastly, the server responds with the actual content.
2256 MockRead("HTTP/1.1 200 OK\r\n"),
2257 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502258 MockRead("Content-Length: 5\r\n\r\n"),
2259 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322260 };
2261
[email protected]2d0a4f92011-05-05 16:38:462262 // An incorrect reconnect would cause this to be read.
2263 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062264 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462265 };
2266
[email protected]31a2bfe2010-02-09 08:03:392267 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2268 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462269 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2270 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072271 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2272 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322273
[email protected]49639fa2011-12-20 23:22:412274 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322275
[email protected]262eec82013-03-19 21:01:362276 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502277 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412278 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422279 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322280
2281 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422282 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322283
[email protected]1c773ea12009-04-28 19:58:422284 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502285 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042286 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322287
[email protected]49639fa2011-12-20 23:22:412288 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322289
[email protected]49639fa2011-12-20 23:22:412290 rv = trans->RestartWithAuth(
2291 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422292 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322293
2294 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422295 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322296
2297 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502298 ASSERT_TRUE(response != NULL);
[email protected]2d2697f92009-02-18 21:00:322299 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502300 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322301}
2302
2303// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312304// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022305TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312306 HttpRequestInfo request;
2307 request.method = "GET";
bncce36dca22015-04-21 22:11:232308 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312309 request.load_flags = 0;
2310
[email protected]bb88e1d32013-05-03 23:11:072311 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272312
[email protected]11203f012009-11-12 23:02:312313 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232314 MockWrite(
2315 "GET / HTTP/1.1\r\n"
2316 "Host: www.example.org\r\n"
2317 "Connection: keep-alive\r\n\r\n"),
2318 // This simulates the seemingly successful write to a closed connection
2319 // if the bug is not fixed.
2320 MockWrite(
2321 "GET / HTTP/1.1\r\n"
2322 "Host: www.example.org\r\n"
2323 "Connection: keep-alive\r\n"
2324 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312325 };
2326
2327 MockRead data_reads1[] = {
2328 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2329 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2330 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2331 MockRead("Content-Length: 14\r\n\r\n"),
2332 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062333 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312334 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062335 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312336 };
2337
2338 // After calling trans->RestartWithAuth(), this is the request we should
2339 // be issuing -- the final header line contains the credentials.
2340 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232341 MockWrite(
2342 "GET / HTTP/1.1\r\n"
2343 "Host: www.example.org\r\n"
2344 "Connection: keep-alive\r\n"
2345 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312346 };
2347
2348 // Lastly, the server responds with the actual content.
2349 MockRead data_reads2[] = {
2350 MockRead("HTTP/1.1 200 OK\r\n"),
2351 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502352 MockRead("Content-Length: 5\r\n\r\n"),
2353 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312354 };
2355
[email protected]31a2bfe2010-02-09 08:03:392356 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2357 data_writes1, arraysize(data_writes1));
2358 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2359 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072360 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2361 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312362
[email protected]49639fa2011-12-20 23:22:412363 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312364
[email protected]262eec82013-03-19 21:01:362365 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502366 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412367 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312368 EXPECT_EQ(ERR_IO_PENDING, rv);
2369
2370 rv = callback1.WaitForResult();
2371 EXPECT_EQ(OK, rv);
2372
2373 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502374 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:042375 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312376
[email protected]49639fa2011-12-20 23:22:412377 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312378
[email protected]49639fa2011-12-20 23:22:412379 rv = trans->RestartWithAuth(
2380 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312381 EXPECT_EQ(ERR_IO_PENDING, rv);
2382
2383 rv = callback2.WaitForResult();
2384 EXPECT_EQ(OK, rv);
2385
2386 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502387 ASSERT_TRUE(response != NULL);
[email protected]11203f012009-11-12 23:02:312388 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502389 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312390}
2391
[email protected]394816e92010-08-03 07:38:592392// Test the request-challenge-retry sequence for basic auth, over a connection
2393// that requires a restart when setting up an SSL tunnel.
ttuttle34f63b52015-03-05 04:33:012394TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
2395 HttpRequestInfo request;
2396 request.method = "GET";
bncce36dca22015-04-21 22:11:232397 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012398 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292399 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012400
2401 // Configure against proxy server "myproxy:70".
2402 session_deps_.proxy_service.reset(
2403 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512404 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012405 session_deps_.net_log = log.bound().net_log();
2406 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2407
2408 // Since we have proxy, should try to establish tunnel.
2409 MockWrite data_writes1[] = {
mmenkee0b5c882015-08-26 20:29:112410 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2411 "Host: www.example.org\r\n"
2412 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012413 };
2414
mmenkee0b5c882015-08-26 20:29:112415 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012416 // connection.
2417 MockRead data_reads1[] = {
2418 // No credentials.
2419 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2420 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:112421 };
ttuttle34f63b52015-03-05 04:33:012422
mmenkee0b5c882015-08-26 20:29:112423 // Since the first connection couldn't be reused, need to establish another
2424 // once given credentials.
2425 MockWrite data_writes2[] = {
2426 // After calling trans->RestartWithAuth(), this is the request we should
2427 // be issuing -- the final header line contains the credentials.
2428 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2429 "Host: www.example.org\r\n"
2430 "Proxy-Connection: keep-alive\r\n"
2431 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2432
2433 MockWrite("GET / HTTP/1.1\r\n"
2434 "Host: www.example.org\r\n"
2435 "Connection: keep-alive\r\n\r\n"),
2436 };
2437
2438 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012439 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2440
2441 MockRead("HTTP/1.1 200 OK\r\n"),
2442 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2443 MockRead("Content-Length: 5\r\n\r\n"),
2444 MockRead(SYNCHRONOUS, "hello"),
2445 };
2446
2447 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2448 data_writes1, arraysize(data_writes1));
2449 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee0b5c882015-08-26 20:29:112450 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2451 data_writes2, arraysize(data_writes2));
2452 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012453 SSLSocketDataProvider ssl(ASYNC, OK);
2454 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2455
2456 TestCompletionCallback callback1;
2457
2458 scoped_ptr<HttpTransaction> trans(
2459 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2460
2461 int rv = trans->Start(&request, callback1.callback(), log.bound());
2462 EXPECT_EQ(ERR_IO_PENDING, rv);
2463
2464 rv = callback1.WaitForResult();
2465 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462466 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012467 log.GetEntries(&entries);
2468 size_t pos = ExpectLogContainsSomewhere(
2469 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2470 NetLog::PHASE_NONE);
2471 ExpectLogContainsSomewhere(
2472 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2473 NetLog::PHASE_NONE);
2474
2475 const HttpResponseInfo* response = trans->GetResponseInfo();
2476 ASSERT_TRUE(response != NULL);
2477 EXPECT_FALSE(response->headers->IsKeepAlive());
2478 ASSERT_FALSE(response->headers.get() == NULL);
2479 EXPECT_EQ(407, response->headers->response_code());
2480 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2481 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2482
2483 LoadTimingInfo load_timing_info;
2484 // CONNECT requests and responses are handled at the connect job level, so
2485 // the transaction does not yet have a connection.
2486 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2487
2488 TestCompletionCallback callback2;
2489
2490 rv =
2491 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2492 EXPECT_EQ(ERR_IO_PENDING, rv);
2493
2494 rv = callback2.WaitForResult();
2495 EXPECT_EQ(OK, rv);
2496
2497 response = trans->GetResponseInfo();
2498 ASSERT_TRUE(response != NULL);
2499
2500 EXPECT_TRUE(response->headers->IsKeepAlive());
2501 EXPECT_EQ(200, response->headers->response_code());
2502 EXPECT_EQ(5, response->headers->GetContentLength());
2503 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2504
2505 // The password prompt info should not be set.
2506 EXPECT_TRUE(response->auth_challenge.get() == NULL);
2507
2508 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2509 TestLoadTimingNotReusedWithPac(load_timing_info,
2510 CONNECT_TIMING_HAS_SSL_TIMES);
2511
2512 trans.reset();
2513 session->CloseAllConnections();
2514}
2515
2516// Test the request-challenge-retry sequence for basic auth, over a connection
2517// that requires a restart when setting up an SSL tunnel.
2518TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:592519 HttpRequestInfo request;
2520 request.method = "GET";
bncce36dca22015-04-21 22:11:232521 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:592522 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292523 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:592524
[email protected]cb9bf6ca2011-01-28 13:15:272525 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072526 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:202527 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512528 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072529 session_deps_.net_log = log.bound().net_log();
2530 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272531
[email protected]394816e92010-08-03 07:38:592532 // Since we have proxy, should try to establish tunnel.
2533 MockWrite data_writes1[] = {
mmenkee0b5c882015-08-26 20:29:112534 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2535 "Host: www.example.org\r\n"
2536 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592537 };
2538
mmenkee0b5c882015-08-26 20:29:112539 // The proxy responds to the connect with a 407, using a non-persistent
[email protected]394816e92010-08-03 07:38:592540 // connection.
2541 MockRead data_reads1[] = {
mmenkee0b5c882015-08-26 20:29:112542 // No credentials.
2543 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2544 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2545 MockRead("Proxy-Connection: close\r\n\r\n"),
2546 };
[email protected]394816e92010-08-03 07:38:592547
mmenkee0b5c882015-08-26 20:29:112548 MockWrite data_writes2[] = {
2549 // After calling trans->RestartWithAuth(), this is the request we should
2550 // be issuing -- the final header line contains the credentials.
2551 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2552 "Host: www.example.org\r\n"
2553 "Proxy-Connection: keep-alive\r\n"
2554 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:592555
mmenkee0b5c882015-08-26 20:29:112556 MockWrite("GET / HTTP/1.1\r\n"
2557 "Host: www.example.org\r\n"
2558 "Connection: keep-alive\r\n\r\n"),
2559 };
2560
2561 MockRead data_reads2[] = {
2562 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2563
2564 MockRead("HTTP/1.1 200 OK\r\n"),
2565 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2566 MockRead("Content-Length: 5\r\n\r\n"),
2567 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:592568 };
2569
2570 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2571 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072572 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee0b5c882015-08-26 20:29:112573 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2574 data_writes2, arraysize(data_writes2));
2575 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:062576 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:072577 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:592578
[email protected]49639fa2011-12-20 23:22:412579 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:592580
[email protected]262eec82013-03-19 21:01:362581 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502582 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:502583
[email protected]49639fa2011-12-20 23:22:412584 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:592585 EXPECT_EQ(ERR_IO_PENDING, rv);
2586
2587 rv = callback1.WaitForResult();
2588 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462589 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402590 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:592591 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402592 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:592593 NetLog::PHASE_NONE);
2594 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402595 entries, pos,
[email protected]394816e92010-08-03 07:38:592596 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2597 NetLog::PHASE_NONE);
2598
2599 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502600 ASSERT_TRUE(response != NULL);
ttuttle34f63b52015-03-05 04:33:012601 EXPECT_FALSE(response->headers->IsKeepAlive());
[email protected]90499482013-06-01 00:39:502602 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]394816e92010-08-03 07:38:592603 EXPECT_EQ(407, response->headers->response_code());
2604 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042605 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:592606
[email protected]029c83b62013-01-24 05:28:202607 LoadTimingInfo load_timing_info;
2608 // CONNECT requests and responses are handled at the connect job level, so
2609 // the transaction does not yet have a connection.
2610 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2611
[email protected]49639fa2011-12-20 23:22:412612 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:592613
[email protected]49639fa2011-12-20 23:22:412614 rv = trans->RestartWithAuth(
2615 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:592616 EXPECT_EQ(ERR_IO_PENDING, rv);
2617
2618 rv = callback2.WaitForResult();
2619 EXPECT_EQ(OK, rv);
2620
2621 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:502622 ASSERT_TRUE(response != NULL);
[email protected]394816e92010-08-03 07:38:592623
2624 EXPECT_TRUE(response->headers->IsKeepAlive());
2625 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:502626 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:592627 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
2628
2629 // The password prompt info should not be set.
2630 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]0b0bf032010-09-21 18:08:502631
[email protected]029c83b62013-01-24 05:28:202632 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2633 TestLoadTimingNotReusedWithPac(load_timing_info,
2634 CONNECT_TIMING_HAS_SSL_TIMES);
2635
[email protected]0b0bf032010-09-21 18:08:502636 trans.reset();
[email protected]102e27c2011-02-23 01:01:312637 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:592638}
2639
[email protected]11203f012009-11-12 23:02:312640// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:012641// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
2642TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
2643 HttpRequestInfo request;
2644 request.method = "GET";
bncce36dca22015-04-21 22:11:232645 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012646 // Ensure that proxy authentication is attempted even
2647 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292648 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012649
2650 // Configure against proxy server "myproxy:70".
2651 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512652 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012653 session_deps_.net_log = log.bound().net_log();
2654 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2655
2656 scoped_ptr<HttpTransaction> trans(
2657 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2658
2659 // Since we have proxy, should try to establish tunnel.
2660 MockWrite data_writes1[] = {
2661 MockWrite(
bncce36dca22015-04-21 22:11:232662 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2663 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012664 "Proxy-Connection: keep-alive\r\n\r\n"),
2665
2666 // After calling trans->RestartWithAuth(), this is the request we should
2667 // be issuing -- the final header line contains the credentials.
2668 MockWrite(
bncce36dca22015-04-21 22:11:232669 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2670 "Host: www.example.org\r\n"
ttuttle34f63b52015-03-05 04:33:012671 "Proxy-Connection: keep-alive\r\n"
2672 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
2673 };
2674
2675 // The proxy responds to the connect with a 407, using a persistent
2676 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
2677 MockRead data_reads1[] = {
2678 // No credentials.
2679 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2680 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2681 MockRead("Proxy-Connection: keep-alive\r\n"),
2682 MockRead("Content-Length: 10\r\n\r\n"),
2683 MockRead("0123456789"),
2684
2685 // Wrong credentials (wrong password).
2686 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2687 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2688 MockRead("Proxy-Connection: keep-alive\r\n"),
2689 MockRead("Content-Length: 10\r\n\r\n"),
2690 // No response body because the test stops reading here.
2691 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
2692 };
2693
2694 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2695 data_writes1, arraysize(data_writes1));
2696 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2697
2698 TestCompletionCallback callback1;
2699
2700 int rv = trans->Start(&request, callback1.callback(), log.bound());
2701 EXPECT_EQ(ERR_IO_PENDING, rv);
2702
2703 rv = callback1.WaitForResult();
2704 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462705 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012706 log.GetEntries(&entries);
2707 size_t pos = ExpectLogContainsSomewhere(
2708 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2709 NetLog::PHASE_NONE);
2710 ExpectLogContainsSomewhere(
2711 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2712 NetLog::PHASE_NONE);
2713
2714 const HttpResponseInfo* response = trans->GetResponseInfo();
2715 ASSERT_TRUE(response);
2716 ASSERT_TRUE(response->headers);
2717 EXPECT_TRUE(response->headers->IsKeepAlive());
2718 EXPECT_EQ(407, response->headers->response_code());
2719 EXPECT_EQ(10, response->headers->GetContentLength());
2720 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2721 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2722
2723 TestCompletionCallback callback2;
2724
2725 // Wrong password (should be "bar").
2726 rv =
2727 trans->RestartWithAuth(AuthCredentials(kFoo, kBaz), callback2.callback());
2728 EXPECT_EQ(ERR_IO_PENDING, rv);
2729
2730 rv = callback2.WaitForResult();
2731 EXPECT_EQ(OK, rv);
2732
2733 response = trans->GetResponseInfo();
2734 ASSERT_TRUE(response);
2735 ASSERT_TRUE(response->headers);
2736 EXPECT_TRUE(response->headers->IsKeepAlive());
2737 EXPECT_EQ(407, response->headers->response_code());
2738 EXPECT_EQ(10, response->headers->GetContentLength());
2739 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2740 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2741
2742 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2743 // out of scope.
2744 session->CloseAllConnections();
2745}
2746
2747// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2748// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
2749TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
[email protected]cb9bf6ca2011-01-28 13:15:272750 HttpRequestInfo request;
2751 request.method = "GET";
bncce36dca22015-04-21 22:11:232752 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272753 // Ensure that proxy authentication is attempted even
2754 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292755 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:272756
[email protected]2d2697f92009-02-18 21:00:322757 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072758 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:512759 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072760 session_deps_.net_log = log.bound().net_log();
2761 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:322762
[email protected]262eec82013-03-19 21:01:362763 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502764 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:322765
[email protected]2d2697f92009-02-18 21:00:322766 // Since we have proxy, should try to establish tunnel.
2767 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232768 MockWrite(
2769 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2770 "Host: www.example.org\r\n"
2771 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322772
bncce36dca22015-04-21 22:11:232773 // After calling trans->RestartWithAuth(), this is the request we should
2774 // be issuing -- the final header line contains the credentials.
2775 MockWrite(
2776 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2777 "Host: www.example.org\r\n"
2778 "Proxy-Connection: keep-alive\r\n"
2779 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322780 };
2781
2782 // The proxy responds to the connect with a 407, using a persistent
2783 // connection.
2784 MockRead data_reads1[] = {
2785 // No credentials.
2786 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2787 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2788 MockRead("Content-Length: 10\r\n\r\n"),
2789 MockRead("0123456789"),
2790
2791 // Wrong credentials (wrong password).
2792 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2793 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2794 MockRead("Content-Length: 10\r\n\r\n"),
2795 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:062796 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]2d2697f92009-02-18 21:00:322797 };
2798
[email protected]31a2bfe2010-02-09 08:03:392799 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2800 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:072801 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d2697f92009-02-18 21:00:322802
[email protected]49639fa2011-12-20 23:22:412803 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322804
[email protected]49639fa2011-12-20 23:22:412805 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]1c773ea12009-04-28 19:58:422806 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322807
2808 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422809 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462810 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:402811 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:392812 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402813 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:392814 NetLog::PHASE_NONE);
2815 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:402816 entries, pos,
[email protected]dbb83db2010-05-11 18:13:392817 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2818 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:322819
[email protected]1c773ea12009-04-28 19:58:422820 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242821 ASSERT_TRUE(response);
2822 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322823 EXPECT_TRUE(response->headers->IsKeepAlive());
2824 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012825 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422826 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042827 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322828
[email protected]49639fa2011-12-20 23:22:412829 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322830
2831 // Wrong password (should be "bar").
[email protected]49639fa2011-12-20 23:22:412832 rv = trans->RestartWithAuth(
2833 AuthCredentials(kFoo, kBaz), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422834 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322835
2836 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422837 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322838
2839 response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242840 ASSERT_TRUE(response);
2841 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:322842 EXPECT_TRUE(response->headers->IsKeepAlive());
2843 EXPECT_EQ(407, response->headers->response_code());
ttuttle34f63b52015-03-05 04:33:012844 EXPECT_EQ(10, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:422845 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:042846 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]e772db3f2010-07-12 18:11:132847
[email protected]e60e47a2010-07-14 03:37:182848 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
2849 // out of scope.
[email protected]102e27c2011-02-23 01:01:312850 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:322851}
2852
mmenkee0b5c882015-08-26 20:29:112853// Test the case a proxy closes a socket while the challenge body is being
2854// drained.
2855TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
2856 HttpRequestInfo request;
2857 request.method = "GET";
2858 request.url = GURL("https://www.example.org/");
2859 // Ensure that proxy authentication is attempted even
2860 // when the no authentication data flag is set.
2861 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
2862
2863 // Configure against proxy server "myproxy:70".
2864 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
2865 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2866
2867 scoped_ptr<HttpTransaction> trans(
2868 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2869
2870 // Since we have proxy, should try to establish tunnel.
2871 MockWrite data_writes1[] = {
2872 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2873 "Host: www.example.org\r\n"
2874 "Proxy-Connection: keep-alive\r\n\r\n"),
2875 };
2876
2877 // The proxy responds to the connect with a 407, using a persistent
2878 // connection.
2879 MockRead data_reads1[] = {
2880 // No credentials.
2881 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2882 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2883 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
2884 // Server hands up in the middle of the body.
2885 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
2886 };
2887
2888 MockWrite data_writes2[] = {
2889 // After calling trans->RestartWithAuth(), this is the request we should
2890 // be issuing -- the final header line contains the credentials.
2891 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
2892 "Host: www.example.org\r\n"
2893 "Proxy-Connection: keep-alive\r\n"
2894 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2895
2896 MockWrite("GET / HTTP/1.1\r\n"
2897 "Host: www.example.org\r\n"
2898 "Connection: keep-alive\r\n\r\n"),
2899 };
2900
2901 MockRead data_reads2[] = {
2902 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
2903
2904 MockRead("HTTP/1.1 200 OK\r\n"),
2905 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2906 MockRead("Content-Length: 5\r\n\r\n"),
2907 MockRead(SYNCHRONOUS, "hello"),
2908 };
2909
2910 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2911 data_writes1, arraysize(data_writes1));
2912 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2913 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2914 data_writes2, arraysize(data_writes2));
2915 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2916 SSLSocketDataProvider ssl(ASYNC, OK);
2917 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2918
2919 TestCompletionCallback callback;
2920
2921 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
2922 EXPECT_EQ(OK, callback.GetResult(rv));
2923
2924 const HttpResponseInfo* response = trans->GetResponseInfo();
2925 ASSERT_TRUE(response);
2926 ASSERT_TRUE(response->headers);
2927 EXPECT_TRUE(response->headers->IsKeepAlive());
2928 EXPECT_EQ(407, response->headers->response_code());
2929 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2930
2931 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
2932 EXPECT_EQ(OK, callback.GetResult(rv));
2933
2934 response = trans->GetResponseInfo();
2935 ASSERT_TRUE(response);
2936 ASSERT_TRUE(response->headers);
2937 EXPECT_TRUE(response->headers->IsKeepAlive());
2938 EXPECT_EQ(200, response->headers->response_code());
2939 std::string body;
2940 EXPECT_EQ(OK, ReadTransaction(trans.get(), &body));
2941 EXPECT_EQ("hello", body);
2942}
2943
[email protected]a8e9b162009-03-12 00:06:442944// Test that we don't read the response body when we fail to establish a tunnel,
2945// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:022946TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:272947 HttpRequestInfo request;
2948 request.method = "GET";
bncce36dca22015-04-21 22:11:232949 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:272950 request.load_flags = 0;
2951
[email protected]a8e9b162009-03-12 00:06:442952 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:072953 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]a8e9b162009-03-12 00:06:442954
[email protected]bb88e1d32013-05-03 23:11:072955 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:442956
[email protected]262eec82013-03-19 21:01:362957 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502958 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:442959
[email protected]a8e9b162009-03-12 00:06:442960 // Since we have proxy, should try to establish tunnel.
2961 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232962 MockWrite(
2963 "CONNECT www.example.org:443 HTTP/1.1\r\n"
2964 "Host: www.example.org\r\n"
2965 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:442966 };
2967
2968 // The proxy responds to the connect with a 407.
2969 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:242970 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
2971 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2972 MockRead("Content-Length: 10\r\n\r\n"),
2973 MockRead("0123456789"), // Should not be reached.
2974 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:442975 };
2976
[email protected]31a2bfe2010-02-09 08:03:392977 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2978 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072979 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:442980
[email protected]49639fa2011-12-20 23:22:412981 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:442982
[email protected]49639fa2011-12-20 23:22:412983 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422984 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:442985
2986 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422987 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:442988
[email protected]1c773ea12009-04-28 19:58:422989 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:242990 ASSERT_TRUE(response);
2991 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:442992 EXPECT_TRUE(response->headers->IsKeepAlive());
2993 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:422994 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:442995
2996 std::string response_data;
2997 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:422998 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:182999
3000 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313001 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443002}
3003
ttuttle7933c112015-01-06 00:55:243004// Test that we don't pass extraneous headers from the proxy's response to the
3005// caller when the proxy responds to CONNECT with 407.
3006TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
3007 HttpRequestInfo request;
3008 request.method = "GET";
bncce36dca22015-04-21 22:11:233009 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243010 request.load_flags = 0;
3011
3012 // Configure against proxy server "myproxy:70".
3013 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
3014
3015 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3016
3017 scoped_ptr<HttpTransaction> trans(
3018 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3019
3020 // Since we have proxy, should try to establish tunnel.
3021 MockWrite data_writes[] = {
3022 MockWrite(
bncce36dca22015-04-21 22:11:233023 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3024 "Host: www.example.org\r\n"
ttuttle7933c112015-01-06 00:55:243025 "Proxy-Connection: keep-alive\r\n\r\n"),
3026 };
3027
3028 // The proxy responds to the connect with a 407.
3029 MockRead data_reads[] = {
3030 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3031 MockRead("X-Foo: bar\r\n"),
3032 MockRead("Set-Cookie: foo=bar\r\n"),
3033 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3034 MockRead("Content-Length: 10\r\n\r\n"),
3035 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
3036 };
3037
3038 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3039 arraysize(data_writes));
3040 session_deps_.socket_factory->AddSocketDataProvider(&data);
3041
3042 TestCompletionCallback callback;
3043
3044 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3045 EXPECT_EQ(ERR_IO_PENDING, rv);
3046
3047 rv = callback.WaitForResult();
3048 EXPECT_EQ(OK, rv);
3049
3050 const HttpResponseInfo* response = trans->GetResponseInfo();
3051 ASSERT_TRUE(response);
3052 ASSERT_TRUE(response->headers);
3053 EXPECT_TRUE(response->headers->IsKeepAlive());
3054 EXPECT_EQ(407, response->headers->response_code());
3055 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3056 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3057 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3058
3059 std::string response_data;
3060 rv = ReadTransaction(trans.get(), &response_data);
3061 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
3062
3063 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3064 session->CloseAllConnections();
3065}
3066
[email protected]8fdbcd22010-05-05 02:54:523067// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3068// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:023069TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523070 HttpRequestInfo request;
3071 request.method = "GET";
bncce36dca22015-04-21 22:11:233072 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523073 request.load_flags = 0;
3074
[email protected]cb9bf6ca2011-01-28 13:15:273075 // We are using a DIRECT connection (i.e. no proxy) for this session.
[email protected]3fe8d2f82013-10-17 08:56:073076 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273077 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:413078 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:273079
[email protected]8fdbcd22010-05-05 02:54:523080 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233081 MockWrite(
3082 "GET / HTTP/1.1\r\n"
3083 "Host: www.example.org\r\n"
3084 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523085 };
3086
3087 MockRead data_reads1[] = {
3088 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3089 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3090 // Large content-length -- won't matter, as connection will be reset.
3091 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063092 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523093 };
3094
3095 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3096 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073097 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523098
[email protected]49639fa2011-12-20 23:22:413099 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523100
[email protected]49639fa2011-12-20 23:22:413101 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:523102 EXPECT_EQ(ERR_IO_PENDING, rv);
3103
3104 rv = callback.WaitForResult();
3105 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
3106}
3107
[email protected]7a67a8152010-11-05 18:31:103108// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3109// through a non-authenticating proxy. The request should fail with
3110// ERR_UNEXPECTED_PROXY_AUTH.
3111// Note that it is impossible to detect if an HTTP server returns a 407 through
3112// a non-authenticating proxy - there is nothing to indicate whether the
3113// response came from the proxy or the server, so it is treated as if the proxy
3114// issued the challenge.
[email protected]23e482282013-06-14 16:08:023115TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:233116 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273117 HttpRequestInfo request;
3118 request.method = "GET";
bncce36dca22015-04-21 22:11:233119 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273120
[email protected]bb88e1d32013-05-03 23:11:073121 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513122 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073123 session_deps_.net_log = log.bound().net_log();
3124 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103125
[email protected]7a67a8152010-11-05 18:31:103126 // Since we have proxy, should try to establish tunnel.
3127 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233128 MockWrite(
3129 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3130 "Host: www.example.org\r\n"
3131 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103132
bncce36dca22015-04-21 22:11:233133 MockWrite(
3134 "GET / HTTP/1.1\r\n"
3135 "Host: www.example.org\r\n"
3136 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103137 };
3138
3139 MockRead data_reads1[] = {
3140 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3141
3142 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3143 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3144 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063145 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103146 };
3147
3148 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3149 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073150 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063151 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073152 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103153
[email protected]49639fa2011-12-20 23:22:413154 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103155
[email protected]262eec82013-03-19 21:01:363156 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503157 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:103158
[email protected]49639fa2011-12-20 23:22:413159 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:103160 EXPECT_EQ(ERR_IO_PENDING, rv);
3161
3162 rv = callback1.WaitForResult();
3163 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
mmenke43758e62015-05-04 21:09:463164 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403165 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103166 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403167 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:103168 NetLog::PHASE_NONE);
3169 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403170 entries, pos,
[email protected]7a67a8152010-11-05 18:31:103171 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3172 NetLog::PHASE_NONE);
3173}
[email protected]2df19bb2010-08-25 20:13:463174
[email protected]029c83b62013-01-24 05:28:203175// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:023176TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203177 HttpRequestInfo request1;
3178 request1.method = "GET";
bncce36dca22015-04-21 22:11:233179 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203180
3181 HttpRequestInfo request2;
3182 request2.method = "GET";
bncce36dca22015-04-21 22:11:233183 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203184
3185 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073186 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:203187 ProxyService::CreateFixed("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513188 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073189 session_deps_.net_log = log.bound().net_log();
3190 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203191
3192 // Since we have proxy, should try to establish tunnel.
3193 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233194 MockWrite(
3195 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3196 "Host: www.example.org\r\n"
3197 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203198
bncce36dca22015-04-21 22:11:233199 MockWrite(
3200 "GET /1 HTTP/1.1\r\n"
3201 "Host: www.example.org\r\n"
3202 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203203
bncce36dca22015-04-21 22:11:233204 MockWrite(
3205 "GET /2 HTTP/1.1\r\n"
3206 "Host: www.example.org\r\n"
3207 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203208 };
3209
3210 // The proxy responds to the connect with a 407, using a persistent
3211 // connection.
3212 MockRead data_reads1[] = {
3213 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3214
3215 MockRead("HTTP/1.1 200 OK\r\n"),
3216 MockRead("Content-Length: 1\r\n\r\n"),
3217 MockRead(SYNCHRONOUS, "1"),
3218
3219 MockRead("HTTP/1.1 200 OK\r\n"),
3220 MockRead("Content-Length: 2\r\n\r\n"),
3221 MockRead(SYNCHRONOUS, "22"),
3222 };
3223
3224 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3225 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073226 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203227 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073228 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203229
3230 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363231 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503232 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203233
3234 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3235 EXPECT_EQ(ERR_IO_PENDING, rv);
3236
3237 rv = callback1.WaitForResult();
3238 EXPECT_EQ(OK, rv);
3239
3240 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3241 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503242 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203243 EXPECT_EQ(1, response1->headers->GetContentLength());
3244
3245 LoadTimingInfo load_timing_info1;
3246 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3247 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
3248
3249 trans1.reset();
3250
3251 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363252 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503253 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203254
3255 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3256 EXPECT_EQ(ERR_IO_PENDING, rv);
3257
3258 rv = callback2.WaitForResult();
3259 EXPECT_EQ(OK, rv);
3260
3261 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3262 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503263 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203264 EXPECT_EQ(2, response2->headers->GetContentLength());
3265
3266 LoadTimingInfo load_timing_info2;
3267 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3268 TestLoadTimingReused(load_timing_info2);
3269
3270 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3271
3272 trans2.reset();
3273 session->CloseAllConnections();
3274}
3275
3276// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:023277TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:203278 HttpRequestInfo request1;
3279 request1.method = "GET";
bncce36dca22015-04-21 22:11:233280 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:203281
3282 HttpRequestInfo request2;
3283 request2.method = "GET";
bncce36dca22015-04-21 22:11:233284 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:203285
3286 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073287 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:203288 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513289 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073290 session_deps_.net_log = log.bound().net_log();
3291 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:203292
3293 // Since we have proxy, should try to establish tunnel.
3294 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233295 MockWrite(
3296 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3297 "Host: www.example.org\r\n"
3298 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203299
bncce36dca22015-04-21 22:11:233300 MockWrite(
3301 "GET /1 HTTP/1.1\r\n"
3302 "Host: www.example.org\r\n"
3303 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203304
bncce36dca22015-04-21 22:11:233305 MockWrite(
3306 "GET /2 HTTP/1.1\r\n"
3307 "Host: www.example.org\r\n"
3308 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:203309 };
3310
3311 // The proxy responds to the connect with a 407, using a persistent
3312 // connection.
3313 MockRead data_reads1[] = {
3314 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3315
3316 MockRead("HTTP/1.1 200 OK\r\n"),
3317 MockRead("Content-Length: 1\r\n\r\n"),
3318 MockRead(SYNCHRONOUS, "1"),
3319
3320 MockRead("HTTP/1.1 200 OK\r\n"),
3321 MockRead("Content-Length: 2\r\n\r\n"),
3322 MockRead(SYNCHRONOUS, "22"),
3323 };
3324
3325 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3326 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073327 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:203328 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073329 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:203330
3331 TestCompletionCallback callback1;
[email protected]262eec82013-03-19 21:01:363332 scoped_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:503333 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203334
3335 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
3336 EXPECT_EQ(ERR_IO_PENDING, rv);
3337
3338 rv = callback1.WaitForResult();
3339 EXPECT_EQ(OK, rv);
3340
3341 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
3342 ASSERT_TRUE(response1 != NULL);
[email protected]90499482013-06-01 00:39:503343 ASSERT_TRUE(response1->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203344 EXPECT_EQ(1, response1->headers->GetContentLength());
3345
3346 LoadTimingInfo load_timing_info1;
3347 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
3348 TestLoadTimingNotReusedWithPac(load_timing_info1,
3349 CONNECT_TIMING_HAS_SSL_TIMES);
3350
3351 trans1.reset();
3352
3353 TestCompletionCallback callback2;
[email protected]262eec82013-03-19 21:01:363354 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:503355 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:203356
3357 rv = trans2->Start(&request2, callback2.callback(), log.bound());
3358 EXPECT_EQ(ERR_IO_PENDING, rv);
3359
3360 rv = callback2.WaitForResult();
3361 EXPECT_EQ(OK, rv);
3362
3363 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
3364 ASSERT_TRUE(response2 != NULL);
[email protected]90499482013-06-01 00:39:503365 ASSERT_TRUE(response2->headers.get() != NULL);
[email protected]029c83b62013-01-24 05:28:203366 EXPECT_EQ(2, response2->headers->GetContentLength());
3367
3368 LoadTimingInfo load_timing_info2;
3369 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
3370 TestLoadTimingReusedWithPac(load_timing_info2);
3371
3372 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
3373
3374 trans2.reset();
3375 session->CloseAllConnections();
3376}
3377
[email protected]2df19bb2010-08-25 20:13:463378// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023379TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273380 HttpRequestInfo request;
3381 request.method = "GET";
bncce36dca22015-04-21 22:11:233382 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273383
[email protected]2df19bb2010-08-25 20:13:463384 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073385 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113386 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513387 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073388 session_deps_.net_log = log.bound().net_log();
3389 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:463390
[email protected]2df19bb2010-08-25 20:13:463391 // Since we have proxy, should use full url
3392 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233393 MockWrite(
3394 "GET http://www.example.org/ HTTP/1.1\r\n"
3395 "Host: www.example.org\r\n"
3396 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:463397 };
3398
3399 MockRead data_reads1[] = {
3400 MockRead("HTTP/1.1 200 OK\r\n"),
3401 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3402 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063403 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:463404 };
3405
3406 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3407 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073408 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063409 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073410 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:463411
[email protected]49639fa2011-12-20 23:22:413412 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:463413
[email protected]262eec82013-03-19 21:01:363414 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503415 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503416
[email protected]49639fa2011-12-20 23:22:413417 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:463418 EXPECT_EQ(ERR_IO_PENDING, rv);
3419
3420 rv = callback1.WaitForResult();
3421 EXPECT_EQ(OK, rv);
3422
[email protected]58e32bb2013-01-21 18:23:253423 LoadTimingInfo load_timing_info;
3424 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3425 TestLoadTimingNotReused(load_timing_info,
3426 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3427
[email protected]2df19bb2010-08-25 20:13:463428 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:503429 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:463430
3431 EXPECT_TRUE(response->headers->IsKeepAlive());
3432 EXPECT_EQ(200, response->headers->response_code());
3433 EXPECT_EQ(100, response->headers->GetContentLength());
3434 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3435
3436 // The password prompt info should not be set.
3437 EXPECT_TRUE(response->auth_challenge.get() == NULL);
3438}
3439
[email protected]7642b5ae2010-09-01 20:55:173440// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023441TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:273442 HttpRequestInfo request;
3443 request.method = "GET";
bncce36dca22015-04-21 22:11:233444 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273445 request.load_flags = 0;
3446
[email protected]7642b5ae2010-09-01 20:55:173447 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073448 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113449 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513450 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073451 session_deps_.net_log = log.bound().net_log();
3452 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:173453
bncce36dca22015-04-21 22:11:233454 // fetch http://www.example.org/ via SPDY
[email protected]cdf8f7e72013-05-23 10:56:463455 scoped_ptr<SpdyFrame> req(
3456 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:133457 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]7642b5ae2010-09-01 20:55:173458
[email protected]23e482282013-06-14 16:08:023459 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3460 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:173461 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133462 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:173463 };
3464
rch8e6c6c42015-05-01 14:05:133465 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3466 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073467 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:173468
[email protected]8ddf8322012-02-23 18:08:063469 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023470 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073471 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:173472
[email protected]49639fa2011-12-20 23:22:413473 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:173474
[email protected]262eec82013-03-19 21:01:363475 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503476 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503477
[email protected]49639fa2011-12-20 23:22:413478 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:173479 EXPECT_EQ(ERR_IO_PENDING, rv);
3480
3481 rv = callback1.WaitForResult();
3482 EXPECT_EQ(OK, rv);
3483
[email protected]58e32bb2013-01-21 18:23:253484 LoadTimingInfo load_timing_info;
3485 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3486 TestLoadTimingNotReused(load_timing_info,
3487 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
3488
[email protected]7642b5ae2010-09-01 20:55:173489 const HttpResponseInfo* response = trans->GetResponseInfo();
3490 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503491 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]7642b5ae2010-09-01 20:55:173492 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3493
3494 std::string response_data;
3495 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233496 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:173497}
3498
[email protected]1c173852014-06-19 12:51:503499// Verifies that a session which races and wins against the owning transaction
3500// (completing prior to host resolution), doesn't fail the transaction.
3501// Regression test for crbug.com/334413.
3502TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
3503 HttpRequestInfo request;
3504 request.method = "GET";
bncce36dca22015-04-21 22:11:233505 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:503506 request.load_flags = 0;
3507
3508 // Configure SPDY proxy server "proxy:70".
3509 session_deps_.proxy_service.reset(
3510 ProxyService::CreateFixed("https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513511 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:503512 session_deps_.net_log = log.bound().net_log();
3513 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3514
bncce36dca22015-04-21 22:11:233515 // Fetch http://www.example.org/ through the SPDY proxy.
[email protected]1c173852014-06-19 12:51:503516 scoped_ptr<SpdyFrame> req(
3517 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:133518 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]1c173852014-06-19 12:51:503519
3520 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3521 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
3522 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133523 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:503524 };
3525
rch8e6c6c42015-05-01 14:05:133526 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3527 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:503528 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
3529
3530 SSLSocketDataProvider ssl(ASYNC, OK);
3531 ssl.SetNextProto(GetParam());
3532 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3533
3534 TestCompletionCallback callback1;
3535
3536 scoped_ptr<HttpTransaction> trans(
3537 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3538
3539 // Stall the hostname resolution begun by the transaction.
3540 session_deps_.host_resolver->set_synchronous_mode(false);
3541 session_deps_.host_resolver->set_ondemand_mode(true);
3542
3543 int rv = trans->Start(&request, callback1.callback(), log.bound());
3544 EXPECT_EQ(ERR_IO_PENDING, rv);
3545
3546 // Race a session to the proxy, which completes first.
3547 session_deps_.host_resolver->set_ondemand_mode(false);
3548 SpdySessionKey key(
3549 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
3550 base::WeakPtr<SpdySession> spdy_session =
3551 CreateSecureSpdySession(session, key, log.bound());
3552
3553 // Unstall the resolution begun by the transaction.
3554 session_deps_.host_resolver->set_ondemand_mode(true);
3555 session_deps_.host_resolver->ResolveAllPending();
3556
3557 EXPECT_FALSE(callback1.have_result());
3558 rv = callback1.WaitForResult();
3559 EXPECT_EQ(OK, rv);
3560
3561 const HttpResponseInfo* response = trans->GetResponseInfo();
3562 ASSERT_TRUE(response != NULL);
3563 ASSERT_TRUE(response->headers.get() != NULL);
3564 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3565
3566 std::string response_data;
3567 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3568 EXPECT_EQ(kUploadData, response_data);
3569}
3570
[email protected]dc7bd1c52010-11-12 00:01:133571// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023572TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:273573 HttpRequestInfo request;
3574 request.method = "GET";
bncce36dca22015-04-21 22:11:233575 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273576 request.load_flags = 0;
3577
[email protected]79cb5c12011-09-12 13:12:043578 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:073579 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:043580 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:513581 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073582 session_deps_.net_log = log.bound().net_log();
3583 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:133584
[email protected]dc7bd1c52010-11-12 00:01:133585 // The first request will be a bare GET, the second request will be a
3586 // GET with a Proxy-Authorization header.
[email protected]ff98d7f02012-03-22 21:44:193587 scoped_ptr<SpdyFrame> req_get(
[email protected]cdf8f7e72013-05-23 10:56:463588 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:133589 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463590 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:133591 };
[email protected]ff98d7f02012-03-22 21:44:193592 scoped_ptr<SpdyFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:463593 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
3594 arraysize(kExtraAuthorizationHeaders) / 2,
3595 false,
3596 3,
3597 LOWEST,
3598 false));
[email protected]dc7bd1c52010-11-12 00:01:133599 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133600 CreateMockWrite(*req_get, 0), CreateMockWrite(*req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:133601 };
3602
3603 // The first response is a 407 proxy authentication challenge, and the second
3604 // response will be a 200 response since the second request includes a valid
3605 // Authorization header.
3606 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:463607 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:133608 };
[email protected]ff98d7f02012-03-22 21:44:193609 scoped_ptr<SpdyFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:023610 spdy_util_.ConstructSpdySynReplyError(
[email protected]dc7bd1c52010-11-12 00:01:133611 "407 Proxy Authentication Required",
3612 kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
3613 1));
[email protected]ff98d7f02012-03-22 21:44:193614 scoped_ptr<SpdyFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:023615 spdy_util_.ConstructSpdyBodyFrame(1, true));
3616 scoped_ptr<SpdyFrame> resp_data(
3617 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
3618 scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:133619 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133620 CreateMockRead(*resp_authentication, 1),
3621 CreateMockRead(*body_authentication, 2),
3622 CreateMockRead(*resp_data, 4),
3623 CreateMockRead(*body_data, 5),
3624 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:133625 };
3626
rch8e6c6c42015-05-01 14:05:133627 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3628 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073629 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:133630
[email protected]8ddf8322012-02-23 18:08:063631 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023632 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073633 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:133634
[email protected]49639fa2011-12-20 23:22:413635 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:133636
[email protected]262eec82013-03-19 21:01:363637 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503638 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:133639
[email protected]49639fa2011-12-20 23:22:413640 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:133641 EXPECT_EQ(ERR_IO_PENDING, rv);
3642
3643 rv = callback1.WaitForResult();
3644 EXPECT_EQ(OK, rv);
3645
3646 const HttpResponseInfo* const response = trans->GetResponseInfo();
3647
3648 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503649 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133650 EXPECT_EQ(407, response->headers->response_code());
3651 EXPECT_TRUE(response->was_fetched_via_spdy);
[email protected]79cb5c12011-09-12 13:12:043652 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:133653
[email protected]49639fa2011-12-20 23:22:413654 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:133655
[email protected]49639fa2011-12-20 23:22:413656 rv = trans->RestartWithAuth(
3657 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:133658 EXPECT_EQ(ERR_IO_PENDING, rv);
3659
3660 rv = callback2.WaitForResult();
3661 EXPECT_EQ(OK, rv);
3662
3663 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
3664
3665 ASSERT_TRUE(response_restart != NULL);
[email protected]90499482013-06-01 00:39:503666 ASSERT_TRUE(response_restart->headers.get() != NULL);
[email protected]dc7bd1c52010-11-12 00:01:133667 EXPECT_EQ(200, response_restart->headers->response_code());
3668 // The password prompt info should not be set.
3669 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
3670}
3671
[email protected]d9da5fe2010-10-13 22:37:163672// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:023673TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:273674 HttpRequestInfo request;
3675 request.method = "GET";
bncce36dca22015-04-21 22:11:233676 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273677 request.load_flags = 0;
3678
[email protected]d9da5fe2010-10-13 22:37:163679 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073680 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113681 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513682 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073683 session_deps_.net_log = log.bound().net_log();
3684 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163685
[email protected]262eec82013-03-19 21:01:363686 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503687 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163688
bncce36dca22015-04-21 22:11:233689 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343690 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233691 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
3692 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:163693
bncce36dca22015-04-21 22:11:233694 const char get[] =
3695 "GET / HTTP/1.1\r\n"
3696 "Host: www.example.org\r\n"
3697 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193698 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:023699 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
3700 scoped_ptr<SpdyFrame> conn_resp(
3701 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:163702 const char resp[] = "HTTP/1.1 200 OK\r\n"
3703 "Content-Length: 10\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:193704 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023705 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:193706 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:023707 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
[email protected]ff98d7f02012-03-22 21:44:193708 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203709 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:043710
3711 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133712 CreateMockWrite(*connect, 0),
3713 CreateMockWrite(*wrapped_get, 2),
3714 CreateMockWrite(*window_update, 6),
[email protected]8d2f7012012-02-16 00:08:043715 };
3716
[email protected]d9da5fe2010-10-13 22:37:163717 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133718 CreateMockRead(*conn_resp, 1, ASYNC),
3719 CreateMockRead(*wrapped_get_resp, 3, ASYNC),
3720 CreateMockRead(*wrapped_body, 4, ASYNC),
3721 CreateMockRead(*wrapped_body, 5, ASYNC),
3722 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:163723 };
3724
rch8e6c6c42015-05-01 14:05:133725 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3726 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073727 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163728
[email protected]8ddf8322012-02-23 18:08:063729 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023730 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073731 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063732 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073733 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163734
[email protected]49639fa2011-12-20 23:22:413735 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163736
[email protected]49639fa2011-12-20 23:22:413737 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163738 EXPECT_EQ(ERR_IO_PENDING, rv);
3739
3740 rv = callback1.WaitForResult();
rch8e6c6c42015-05-01 14:05:133741 ASSERT_EQ(OK, rv);
[email protected]d9da5fe2010-10-13 22:37:163742
[email protected]58e32bb2013-01-21 18:23:253743 LoadTimingInfo load_timing_info;
3744 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3745 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3746
[email protected]d9da5fe2010-10-13 22:37:163747 const HttpResponseInfo* response = trans->GetResponseInfo();
3748 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503749 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163750 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3751
3752 std::string response_data;
3753 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
3754 EXPECT_EQ("1234567890", response_data);
3755}
3756
3757// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:023758TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
[email protected]cb9bf6ca2011-01-28 13:15:273759 HttpRequestInfo request;
3760 request.method = "GET";
bncce36dca22015-04-21 22:11:233761 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273762 request.load_flags = 0;
3763
[email protected]d9da5fe2010-10-13 22:37:163764 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073765 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113766 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513767 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073768 session_deps_.net_log = log.bound().net_log();
3769 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163770
[email protected]262eec82013-03-19 21:01:363771 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503772 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163773
bncce36dca22015-04-21 22:11:233774 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343775 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233776 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
3777 // fetch https://www.example.org/ via SPDY
3778 const char kMyUrl[] = "https://www.example.org/";
[email protected]cdf8f7e72013-05-23 10:56:463779 scoped_ptr<SpdyFrame> get(
3780 spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:023781 scoped_ptr<SpdyFrame> wrapped_get(
3782 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
3783 scoped_ptr<SpdyFrame> conn_resp(
3784 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3785 scoped_ptr<SpdyFrame> get_resp(
3786 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]ff98d7f02012-03-22 21:44:193787 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:023788 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
3789 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3790 scoped_ptr<SpdyFrame> wrapped_body(
3791 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
[email protected]ff98d7f02012-03-22 21:44:193792 scoped_ptr<SpdyFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:203793 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]ff98d7f02012-03-22 21:44:193794 scoped_ptr<SpdyFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:203795 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:043796
3797 MockWrite spdy_writes[] = {
rch32320842015-05-16 15:57:093798 CreateMockWrite(*connect, 0),
3799 CreateMockWrite(*wrapped_get, 2),
3800 CreateMockWrite(*window_update_get_resp, 6),
[email protected]8d2f7012012-02-16 00:08:043801 CreateMockWrite(*window_update_body, 7),
3802 };
3803
[email protected]d9da5fe2010-10-13 22:37:163804 MockRead spdy_reads[] = {
rch32320842015-05-16 15:57:093805 CreateMockRead(*conn_resp, 1, ASYNC),
3806 MockRead(ASYNC, ERR_IO_PENDING, 3),
rch8e6c6c42015-05-01 14:05:133807 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
rch32320842015-05-16 15:57:093808 CreateMockRead(*wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:133809 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:163810 };
3811
rch32320842015-05-16 15:57:093812 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3813 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073814 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163815
[email protected]8ddf8322012-02-23 18:08:063816 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023817 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073818 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063819 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023820 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073821 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163822
[email protected]49639fa2011-12-20 23:22:413823 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163824
[email protected]49639fa2011-12-20 23:22:413825 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163826 EXPECT_EQ(ERR_IO_PENDING, rv);
3827
rch32320842015-05-16 15:57:093828 // Allow the SpdyProxyClientSocket's write callback to complete.
3829 base::MessageLoop::current()->RunUntilIdle();
3830 // Now allow the read of the response to complete.
3831 spdy_data.CompleteRead();
[email protected]d9da5fe2010-10-13 22:37:163832 rv = callback1.WaitForResult();
3833 EXPECT_EQ(OK, rv);
3834
[email protected]58e32bb2013-01-21 18:23:253835 LoadTimingInfo load_timing_info;
3836 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3837 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
3838
[email protected]d9da5fe2010-10-13 22:37:163839 const HttpResponseInfo* response = trans->GetResponseInfo();
3840 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:503841 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d9da5fe2010-10-13 22:37:163842 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
3843
3844 std::string response_data;
3845 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:233846 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:163847}
3848
3849// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:023850TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:273851 HttpRequestInfo request;
3852 request.method = "GET";
bncce36dca22015-04-21 22:11:233853 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273854 request.load_flags = 0;
3855
[email protected]d9da5fe2010-10-13 22:37:163856 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073857 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:113858 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513859 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073860 session_deps_.net_log = log.bound().net_log();
3861 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:163862
[email protected]262eec82013-03-19 21:01:363863 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503864 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:163865
bncce36dca22015-04-21 22:11:233866 // CONNECT to www.example.org:443 via SPDY
lgarrona91df87f2014-12-05 00:51:343867 scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233868 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:203869 scoped_ptr<SpdyFrame> get(
3870 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:163871
3872 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:133873 CreateMockWrite(*connect, 0), CreateMockWrite(*get, 2),
[email protected]d9da5fe2010-10-13 22:37:163874 };
3875
[email protected]23e482282013-06-14 16:08:023876 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
3877 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:163878 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:133879 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:163880 };
3881
rch8e6c6c42015-05-01 14:05:133882 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3883 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:073884 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:163885
[email protected]8ddf8322012-02-23 18:08:063886 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023887 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073888 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:063889 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:023890 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:073891 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:163892
[email protected]49639fa2011-12-20 23:22:413893 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:163894
[email protected]49639fa2011-12-20 23:22:413895 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:163896 EXPECT_EQ(ERR_IO_PENDING, rv);
3897
3898 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:173899 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:163900
[email protected]4eddbc732012-08-09 05:40:173901 // TODO(ttuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:163902}
3903
[email protected]f6c63db52013-02-02 00:35:223904// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
3905// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:023906TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:223907 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
3908 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:073909 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:223910 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:513911 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073912 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:223913 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:503914 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:223915
3916 HttpRequestInfo request1;
3917 request1.method = "GET";
bncce36dca22015-04-21 22:11:233918 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:223919 request1.load_flags = 0;
3920
3921 HttpRequestInfo request2;
3922 request2.method = "GET";
bncce36dca22015-04-21 22:11:233923 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:223924 request2.load_flags = 0;
3925
bncce36dca22015-04-21 22:11:233926 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:343927 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:233928 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:023929 scoped_ptr<SpdyFrame> conn_resp1(
3930 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:223931
bncce36dca22015-04-21 22:11:233932 // Fetch https://www.example.org/ via HTTP.
3933 const char get1[] =
3934 "GET / HTTP/1.1\r\n"
3935 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223936 "Connection: keep-alive\r\n\r\n";
3937 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:023938 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:223939 const char resp1[] = "HTTP/1.1 200 OK\r\n"
3940 "Content-Length: 1\r\n\r\n";
3941 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:023942 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
3943 scoped_ptr<SpdyFrame> wrapped_body1(
3944 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:223945 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:203946 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:223947
bncce36dca22015-04-21 22:11:233948 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:293949 SpdyHeaderBlock connect2_block;
3950 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
bnc9b79a572015-09-02 12:25:033951 if (GetParam() == kProtoHTTP2) {
bnc6b996d532015-07-29 10:51:323952 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
3953 } else {
3954 connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
3955 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
3956 }
[email protected]745aa9c2014-06-27 02:21:293957 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]f6c63db52013-02-02 00:35:223958 scoped_ptr<SpdyFrame> connect2(
[email protected]745aa9c2014-06-27 02:21:293959 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
[email protected]601e03f12014-04-06 16:26:393960
[email protected]23e482282013-06-14 16:08:023961 scoped_ptr<SpdyFrame> conn_resp2(
3962 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:223963
bncce36dca22015-04-21 22:11:233964 // Fetch https://mail.example.org/ via HTTP.
3965 const char get2[] =
3966 "GET / HTTP/1.1\r\n"
3967 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:223968 "Connection: keep-alive\r\n\r\n";
3969 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:023970 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:223971 const char resp2[] = "HTTP/1.1 200 OK\r\n"
3972 "Content-Length: 2\r\n\r\n";
3973 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:023974 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:223975 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:023976 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:223977
3978 MockWrite spdy_writes[] = {
3979 CreateMockWrite(*connect1, 0),
3980 CreateMockWrite(*wrapped_get1, 2),
3981 CreateMockWrite(*connect2, 5),
3982 CreateMockWrite(*wrapped_get2, 7),
3983 };
3984
3985 MockRead spdy_reads[] = {
3986 CreateMockRead(*conn_resp1, 1, ASYNC),
3987 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
3988 CreateMockRead(*wrapped_body1, 4, ASYNC),
3989 CreateMockRead(*conn_resp2, 6, ASYNC),
3990 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
3991 CreateMockRead(*wrapped_body2, 9, ASYNC),
3992 MockRead(ASYNC, 0, 10),
3993 };
3994
mmenke11eb5152015-06-09 14:50:503995 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
3996 arraysize(spdy_writes));
3997 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:223998
3999 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024000 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504001 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224002 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504003 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224004 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504005 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:224006
4007 TestCompletionCallback callback;
4008
[email protected]262eec82013-03-19 21:01:364009 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504010 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224011 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504012 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224013
4014 LoadTimingInfo load_timing_info;
4015 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4016 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4017
4018 const HttpResponseInfo* response = trans->GetResponseInfo();
4019 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504020 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224021 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4022
4023 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294024 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:504025 rv = trans->Read(buf.get(), 256, callback.callback());
4026 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224027
[email protected]262eec82013-03-19 21:01:364028 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504029 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224030 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504031 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224032
4033 LoadTimingInfo load_timing_info2;
4034 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4035 // Even though the SPDY connection is reused, a new tunnelled connection has
4036 // to be created, so the socket's load timing looks like a fresh connection.
4037 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
4038
4039 // The requests should have different IDs, since they each are using their own
4040 // separate stream.
4041 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4042
mmenke11eb5152015-06-09 14:50:504043 rv = trans2->Read(buf.get(), 256, callback.callback());
4044 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224045}
4046
4047// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4048// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:024049TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224050 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
4051 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:074052 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:224053 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:514054 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074055 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:224056 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504057 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224058
4059 HttpRequestInfo request1;
4060 request1.method = "GET";
bncce36dca22015-04-21 22:11:234061 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224062 request1.load_flags = 0;
4063
4064 HttpRequestInfo request2;
4065 request2.method = "GET";
bncce36dca22015-04-21 22:11:234066 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:224067 request2.load_flags = 0;
4068
bncce36dca22015-04-21 22:11:234069 // CONNECT to www.example.org:443 via SPDY.
lgarrona91df87f2014-12-05 00:51:344070 scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234071 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]23e482282013-06-14 16:08:024072 scoped_ptr<SpdyFrame> conn_resp1(
4073 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224074
bncce36dca22015-04-21 22:11:234075 // Fetch https://www.example.org/ via HTTP.
4076 const char get1[] =
4077 "GET / HTTP/1.1\r\n"
4078 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224079 "Connection: keep-alive\r\n\r\n";
4080 scoped_ptr<SpdyFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:024081 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224082 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4083 "Content-Length: 1\r\n\r\n";
4084 scoped_ptr<SpdyFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:024085 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
4086 scoped_ptr<SpdyFrame> wrapped_body1(
4087 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
[email protected]f6c63db52013-02-02 00:35:224088 scoped_ptr<SpdyFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204089 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:224090
bncce36dca22015-04-21 22:11:234091 // Fetch https://www.example.org/2 via HTTP.
4092 const char get2[] =
4093 "GET /2 HTTP/1.1\r\n"
4094 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224095 "Connection: keep-alive\r\n\r\n";
4096 scoped_ptr<SpdyFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:024097 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:224098 const char resp2[] = "HTTP/1.1 200 OK\r\n"
4099 "Content-Length: 2\r\n\r\n";
4100 scoped_ptr<SpdyFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:024101 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
[email protected]f6c63db52013-02-02 00:35:224102 scoped_ptr<SpdyFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:024103 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:224104
4105 MockWrite spdy_writes[] = {
4106 CreateMockWrite(*connect1, 0),
4107 CreateMockWrite(*wrapped_get1, 2),
4108 CreateMockWrite(*wrapped_get2, 5),
4109 };
4110
4111 MockRead spdy_reads[] = {
4112 CreateMockRead(*conn_resp1, 1, ASYNC),
4113 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
4114 CreateMockRead(*wrapped_body1, 4, ASYNC),
4115 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
4116 CreateMockRead(*wrapped_body2, 7, ASYNC),
4117 MockRead(ASYNC, 0, 8),
4118 };
4119
mmenke11eb5152015-06-09 14:50:504120 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4121 arraysize(spdy_writes));
4122 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224123
4124 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024125 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504126 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224127 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:504128 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:224129
4130 TestCompletionCallback callback;
4131
[email protected]262eec82013-03-19 21:01:364132 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504133 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224134 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
4135 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f6c63db52013-02-02 00:35:224136
4137 rv = callback.WaitForResult();
4138 EXPECT_EQ(OK, rv);
4139
4140 LoadTimingInfo load_timing_info;
4141 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4142 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4143
4144 const HttpResponseInfo* response = trans->GetResponseInfo();
4145 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504146 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224147 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4148
4149 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294150 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:504151 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224152 trans.reset();
4153
[email protected]262eec82013-03-19 21:01:364154 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504155 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224156 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
4157 EXPECT_EQ(ERR_IO_PENDING, rv);
4158
[email protected]f6c63db52013-02-02 00:35:224159 rv = callback.WaitForResult();
4160 EXPECT_EQ(OK, rv);
4161
4162 LoadTimingInfo load_timing_info2;
4163 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4164 TestLoadTimingReused(load_timing_info2);
4165
4166 // The requests should have the same ID.
4167 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4168
[email protected]90499482013-06-01 00:39:504169 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:224170}
4171
4172// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
4173// Proxy to different servers.
mmenke11eb5152015-06-09 14:50:504174TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:224175 // Configure against https proxy server "proxy:70".
[email protected]bb88e1d32013-05-03 23:11:074176 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]f6c63db52013-02-02 00:35:224177 "https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:514178 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074179 session_deps_.net_log = log.bound().net_log();
[email protected]f6c63db52013-02-02 00:35:224180 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504181 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224182
4183 HttpRequestInfo request1;
4184 request1.method = "GET";
bncce36dca22015-04-21 22:11:234185 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224186 request1.load_flags = 0;
4187
4188 HttpRequestInfo request2;
4189 request2.method = "GET";
bncce36dca22015-04-21 22:11:234190 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224191 request2.load_flags = 0;
4192
bncce36dca22015-04-21 22:11:234193 // http://www.example.org/
[email protected]23e482282013-06-14 16:08:024194 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:234195 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294196 scoped_ptr<SpdyFrame> get1(
4197 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024198 scoped_ptr<SpdyFrame> get_resp1(
4199 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4200 scoped_ptr<SpdyFrame> body1(
4201 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
[email protected]f6c63db52013-02-02 00:35:224202
bncce36dca22015-04-21 22:11:234203 // http://mail.example.org/
[email protected]23e482282013-06-14 16:08:024204 scoped_ptr<SpdyHeaderBlock> headers2(
bncce36dca22015-04-21 22:11:234205 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
[email protected]745aa9c2014-06-27 02:21:294206 scoped_ptr<SpdyFrame> get2(
4207 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
[email protected]23e482282013-06-14 16:08:024208 scoped_ptr<SpdyFrame> get_resp2(
4209 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
4210 scoped_ptr<SpdyFrame> body2(
4211 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:224212
4213 MockWrite spdy_writes[] = {
4214 CreateMockWrite(*get1, 0),
4215 CreateMockWrite(*get2, 3),
4216 };
4217
4218 MockRead spdy_reads[] = {
4219 CreateMockRead(*get_resp1, 1, ASYNC),
4220 CreateMockRead(*body1, 2, ASYNC),
4221 CreateMockRead(*get_resp2, 4, ASYNC),
4222 CreateMockRead(*body2, 5, ASYNC),
4223 MockRead(ASYNC, 0, 6),
4224 };
4225
mmenke11eb5152015-06-09 14:50:504226 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4227 arraysize(spdy_writes));
4228 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:224229
4230 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:024231 ssl.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:504232 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:224233
4234 TestCompletionCallback callback;
4235
[email protected]262eec82013-03-19 21:01:364236 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504237 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224238 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504239 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224240
4241 LoadTimingInfo load_timing_info;
4242 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4243 TestLoadTimingNotReused(load_timing_info,
4244 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4245
4246 const HttpResponseInfo* response = trans->GetResponseInfo();
4247 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504248 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]f6c63db52013-02-02 00:35:224249 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4250
4251 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:294252 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:504253 rv = trans->Read(buf.get(), 256, callback.callback());
4254 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224255 // Delete the first request, so the second one can reuse the socket.
4256 trans.reset();
4257
[email protected]262eec82013-03-19 21:01:364258 scoped_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504259 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:224260 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:504261 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224262
4263 LoadTimingInfo load_timing_info2;
4264 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4265 TestLoadTimingReused(load_timing_info2);
4266
4267 // The requests should have the same ID.
4268 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
4269
mmenke11eb5152015-06-09 14:50:504270 rv = trans2->Read(buf.get(), 256, callback.callback());
4271 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:224272}
4273
[email protected]2df19bb2010-08-25 20:13:464274// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:024275TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:464276 HttpRequestInfo request;
4277 request.method = "GET";
bncce36dca22015-04-21 22:11:234278 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:464279 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:294280 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:464281
[email protected]79cb5c12011-09-12 13:12:044282 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074283 session_deps_.proxy_service.reset(
[email protected]79cb5c12011-09-12 13:12:044284 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:514285 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074286 session_deps_.net_log = log.bound().net_log();
4287 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274288
[email protected]2df19bb2010-08-25 20:13:464289 // Since we have proxy, should use full url
4290 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234291 MockWrite(
4292 "GET http://www.example.org/ HTTP/1.1\r\n"
4293 "Host: www.example.org\r\n"
4294 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464295
bncce36dca22015-04-21 22:11:234296 // After calling trans->RestartWithAuth(), this is the request we should
4297 // be issuing -- the final header line contains the credentials.
4298 MockWrite(
4299 "GET http://www.example.org/ HTTP/1.1\r\n"
4300 "Host: www.example.org\r\n"
4301 "Proxy-Connection: keep-alive\r\n"
4302 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464303 };
4304
4305 // The proxy responds to the GET with a 407, using a persistent
4306 // connection.
4307 MockRead data_reads1[] = {
4308 // No credentials.
4309 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4310 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4311 MockRead("Proxy-Connection: keep-alive\r\n"),
4312 MockRead("Content-Length: 0\r\n\r\n"),
4313
4314 MockRead("HTTP/1.1 200 OK\r\n"),
4315 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4316 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064317 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464318 };
4319
4320 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4321 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074322 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064323 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464325
[email protected]49639fa2011-12-20 23:22:414326 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464327
[email protected]262eec82013-03-19 21:01:364328 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504329 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504330
[email protected]49639fa2011-12-20 23:22:414331 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464332 EXPECT_EQ(ERR_IO_PENDING, rv);
4333
4334 rv = callback1.WaitForResult();
4335 EXPECT_EQ(OK, rv);
4336
[email protected]58e32bb2013-01-21 18:23:254337 LoadTimingInfo load_timing_info;
4338 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4339 TestLoadTimingNotReused(load_timing_info,
4340 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4341
[email protected]2df19bb2010-08-25 20:13:464342 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504343 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:504344 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]2df19bb2010-08-25 20:13:464345 EXPECT_EQ(407, response->headers->response_code());
4346 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:044347 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:464348
[email protected]49639fa2011-12-20 23:22:414349 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:464350
[email protected]49639fa2011-12-20 23:22:414351 rv = trans->RestartWithAuth(
4352 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:464353 EXPECT_EQ(ERR_IO_PENDING, rv);
4354
4355 rv = callback2.WaitForResult();
4356 EXPECT_EQ(OK, rv);
4357
[email protected]58e32bb2013-01-21 18:23:254358 load_timing_info = LoadTimingInfo();
4359 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4360 // Retrying with HTTP AUTH is considered to be reusing a socket.
4361 TestLoadTimingReused(load_timing_info);
4362
[email protected]2df19bb2010-08-25 20:13:464363 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504364 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:464365
4366 EXPECT_TRUE(response->headers->IsKeepAlive());
4367 EXPECT_EQ(200, response->headers->response_code());
4368 EXPECT_EQ(100, response->headers->GetContentLength());
4369 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4370
4371 // The password prompt info should not be set.
4372 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4373}
4374
[email protected]23e482282013-06-14 16:08:024375void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:084376 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:424377 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:084378 request.method = "GET";
bncce36dca22015-04-21 22:11:234379 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:084380 request.load_flags = 0;
4381
[email protected]cb9bf6ca2011-01-28 13:15:274382 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:074383 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bb88e1d32013-05-03 23:11:074384 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274385
[email protected]c744cf22009-02-27 07:28:084386 // Since we have proxy, should try to establish tunnel.
4387 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:234388 MockWrite(
4389 "CONNECT www.example.org:443 HTTP/1.1\r\n"
4390 "Host: www.example.org\r\n"
4391 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:084392 };
4393
4394 MockRead data_reads[] = {
4395 status,
4396 MockRead("Content-Length: 10\r\n\r\n"),
4397 // No response body because the test stops reading here.
[email protected]8ddf8322012-02-23 18:08:064398 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]c744cf22009-02-27 07:28:084399 };
4400
[email protected]31a2bfe2010-02-09 08:03:394401 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
4402 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:074403 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:084404
[email protected]49639fa2011-12-20 23:22:414405 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:084406
[email protected]262eec82013-03-19 21:01:364407 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504408 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504409
[email protected]49639fa2011-12-20 23:22:414410 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424411 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:084412
4413 rv = callback.WaitForResult();
4414 EXPECT_EQ(expected_status, rv);
4415}
4416
[email protected]23e482282013-06-14 16:08:024417void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:234418 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:084419 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:424420 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:084421}
4422
[email protected]23e482282013-06-14 16:08:024423TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:084424 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
4425}
4426
[email protected]23e482282013-06-14 16:08:024427TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:084428 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
4429}
4430
[email protected]23e482282013-06-14 16:08:024431TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:084432 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
4433}
4434
[email protected]23e482282013-06-14 16:08:024435TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:084436 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
4437}
4438
[email protected]23e482282013-06-14 16:08:024439TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:084440 ConnectStatusHelper(
4441 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
4442}
4443
[email protected]23e482282013-06-14 16:08:024444TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:084445 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
4446}
4447
[email protected]23e482282013-06-14 16:08:024448TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:084449 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
4450}
4451
[email protected]23e482282013-06-14 16:08:024452TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:084453 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
4454}
4455
[email protected]23e482282013-06-14 16:08:024456TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:084457 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
4458}
4459
[email protected]23e482282013-06-14 16:08:024460TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:084461 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
4462}
4463
[email protected]23e482282013-06-14 16:08:024464TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:084465 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
4466}
4467
[email protected]23e482282013-06-14 16:08:024468TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:084469 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
4470}
4471
[email protected]23e482282013-06-14 16:08:024472TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:084473 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
4474}
4475
[email protected]23e482282013-06-14 16:08:024476TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:084477 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
4478}
4479
[email protected]23e482282013-06-14 16:08:024480TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:084481 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
4482}
4483
[email protected]23e482282013-06-14 16:08:024484TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:084485 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
4486}
4487
[email protected]0a17aab32014-04-24 03:32:374488TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
4489 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
4490}
4491
[email protected]23e482282013-06-14 16:08:024492TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:084493 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
4494}
4495
[email protected]23e482282013-06-14 16:08:024496TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:084497 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
4498}
4499
[email protected]23e482282013-06-14 16:08:024500TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:084501 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
4502}
4503
[email protected]23e482282013-06-14 16:08:024504TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:084505 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
4506}
4507
[email protected]23e482282013-06-14 16:08:024508TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:084509 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
4510}
4511
[email protected]23e482282013-06-14 16:08:024512TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:084513 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
4514}
4515
[email protected]23e482282013-06-14 16:08:024516TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:084517 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
4518}
4519
[email protected]23e482282013-06-14 16:08:024520TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:084521 ConnectStatusHelperWithExpectedStatus(
4522 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:544523 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:084524}
4525
[email protected]23e482282013-06-14 16:08:024526TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:084527 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
4528}
4529
[email protected]23e482282013-06-14 16:08:024530TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:084531 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
4532}
4533
[email protected]23e482282013-06-14 16:08:024534TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:084535 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
4536}
4537
[email protected]23e482282013-06-14 16:08:024538TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:084539 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
4540}
4541
[email protected]23e482282013-06-14 16:08:024542TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:084543 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
4544}
4545
[email protected]23e482282013-06-14 16:08:024546TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:084547 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
4548}
4549
[email protected]23e482282013-06-14 16:08:024550TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:084551 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
4552}
4553
[email protected]23e482282013-06-14 16:08:024554TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:084555 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
4556}
4557
[email protected]23e482282013-06-14 16:08:024558TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:084559 ConnectStatusHelper(
4560 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
4561}
4562
[email protected]23e482282013-06-14 16:08:024563TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:084564 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
4565}
4566
[email protected]23e482282013-06-14 16:08:024567TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:084568 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
4569}
4570
[email protected]23e482282013-06-14 16:08:024571TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:084572 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
4573}
4574
[email protected]23e482282013-06-14 16:08:024575TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:084576 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
4577}
4578
[email protected]23e482282013-06-14 16:08:024579TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:084580 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
4581}
4582
[email protected]23e482282013-06-14 16:08:024583TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:084584 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
4585}
4586
[email protected]23e482282013-06-14 16:08:024587TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:084588 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
4589}
4590
[email protected]038e9a32008-10-08 22:40:164591// Test the flow when both the proxy server AND origin server require
4592// authentication. Again, this uses basic auth for both since that is
4593// the simplest to mock.
[email protected]23e482282013-06-14 16:08:024594TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:274595 HttpRequestInfo request;
4596 request.method = "GET";
bncce36dca22015-04-21 22:11:234597 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274598 request.load_flags = 0;
4599
[email protected]038e9a32008-10-08 22:40:164600 // Configure against proxy server "myproxy:70".
[email protected]3fe8d2f82013-10-17 08:56:074601 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
4602 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
4603
4604 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:414605 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:164606
[email protected]f9ee6b52008-11-08 06:46:234607 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234608 MockWrite(
4609 "GET http://www.example.org/ HTTP/1.1\r\n"
4610 "Host: www.example.org\r\n"
4611 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:234612 };
4613
[email protected]038e9a32008-10-08 22:40:164614 MockRead data_reads1[] = {
4615 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
4616 // Give a couple authenticate options (only the middle one is actually
4617 // supported).
[email protected]22927ad2009-09-21 19:56:194618 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:164619 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4620 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
4621 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4622 // Large content-length -- won't matter, as connection will be reset.
4623 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064624 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:164625 };
4626
4627 // After calling trans->RestartWithAuth() the first time, this is the
4628 // request we should be issuing -- the final header line contains the
4629 // proxy's credentials.
4630 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:234631 MockWrite(
4632 "GET http://www.example.org/ HTTP/1.1\r\n"
4633 "Host: www.example.org\r\n"
4634 "Proxy-Connection: keep-alive\r\n"
4635 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164636 };
4637
4638 // Now the proxy server lets the request pass through to origin server.
4639 // The origin server responds with a 401.
4640 MockRead data_reads2[] = {
4641 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
4642 // Note: We are using the same realm-name as the proxy server. This is
4643 // completely valid, as realms are unique across hosts.
4644 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4645 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4646 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064647 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:164648 };
4649
4650 // After calling trans->RestartWithAuth() the second time, we should send
4651 // the credentials for both the proxy and origin server.
4652 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:234653 MockWrite(
4654 "GET http://www.example.org/ HTTP/1.1\r\n"
4655 "Host: www.example.org\r\n"
4656 "Proxy-Connection: keep-alive\r\n"
4657 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
4658 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:164659 };
4660
4661 // Lastly we get the desired content.
4662 MockRead data_reads3[] = {
4663 MockRead("HTTP/1.0 200 OK\r\n"),
4664 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4665 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064666 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:164667 };
4668
[email protected]31a2bfe2010-02-09 08:03:394669 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4670 data_writes1, arraysize(data_writes1));
4671 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4672 data_writes2, arraysize(data_writes2));
4673 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4674 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074675 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4676 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4677 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:164678
[email protected]49639fa2011-12-20 23:22:414679 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:164680
[email protected]49639fa2011-12-20 23:22:414681 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424682 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164683
4684 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424685 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164686
[email protected]1c773ea12009-04-28 19:58:424687 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504688 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044689 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164690
[email protected]49639fa2011-12-20 23:22:414691 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:164692
[email protected]49639fa2011-12-20 23:22:414693 rv = trans->RestartWithAuth(
4694 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:424695 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164696
4697 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424698 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164699
4700 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504701 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:044702 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:164703
[email protected]49639fa2011-12-20 23:22:414704 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:164705
[email protected]49639fa2011-12-20 23:22:414706 rv = trans->RestartWithAuth(
4707 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424708 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:164709
4710 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424711 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:164712
4713 response = trans->GetResponseInfo();
4714 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4715 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:164716}
[email protected]4ddaf2502008-10-23 18:26:194717
[email protected]ea9dc9a2009-09-05 00:43:324718// For the NTLM implementation using SSPI, we skip the NTLM tests since we
4719// can't hook into its internals to cause it to generate predictable NTLM
4720// authorization headers.
4721#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:294722// The NTLM authentication unit tests were generated by capturing the HTTP
4723// requests and responses using Fiddler 2 and inspecting the generated random
4724// bytes in the debugger.
4725
4726// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:024727TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:424728 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:244729 request.method = "GET";
4730 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:544731
4732 // Ensure load is not disrupted by flags which suppress behaviour specific
4733 // to other auth schemes.
4734 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:244735
[email protected]cb9bf6ca2011-01-28 13:15:274736 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
4737 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074738 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274739
[email protected]3f918782009-02-28 01:29:244740 MockWrite data_writes1[] = {
4741 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4742 "Host: 172.22.68.17\r\n"
4743 "Connection: keep-alive\r\n\r\n"),
4744 };
4745
4746 MockRead data_reads1[] = {
4747 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044748 // Negotiate and NTLM are often requested together. However, we only want
4749 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4750 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:244751 MockRead("WWW-Authenticate: NTLM\r\n"),
4752 MockRead("Connection: close\r\n"),
4753 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364754 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244755 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064756 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:244757 };
4758
4759 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224760 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:244761 // request we should be issuing -- the final header line contains a Type
4762 // 1 message.
4763 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4764 "Host: 172.22.68.17\r\n"
4765 "Connection: keep-alive\r\n"
4766 "Authorization: NTLM "
4767 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4768
4769 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4770 // (the credentials for the origin server). The second request continues
4771 // on the same connection.
4772 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4773 "Host: 172.22.68.17\r\n"
4774 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:294775 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4776 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4777 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
4778 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
4779 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244780 };
4781
4782 MockRead data_reads2[] = {
4783 // The origin server responds with a Type 2 message.
4784 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4785 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:294786 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:244787 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4788 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4789 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4790 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4791 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4792 "BtAAAAAAA=\r\n"),
4793 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364794 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:244795 MockRead("You are not authorized to view this page\r\n"),
4796
4797 // Lastly we get the desired content.
4798 MockRead("HTTP/1.1 200 OK\r\n"),
4799 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4800 MockRead("Content-Length: 13\r\n\r\n"),
4801 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064802 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:244803 };
4804
[email protected]31a2bfe2010-02-09 08:03:394805 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4806 data_writes1, arraysize(data_writes1));
4807 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4808 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:074809 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4810 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:244811
[email protected]49639fa2011-12-20 23:22:414812 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:244813
[email protected]262eec82013-03-19 21:01:364814 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504815 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504816
[email protected]49639fa2011-12-20 23:22:414817 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424818 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244819
4820 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424821 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244822
[email protected]0757e7702009-03-27 04:00:224823 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4824
[email protected]1c773ea12009-04-28 19:58:424825 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:044826 ASSERT_FALSE(response == NULL);
4827 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:244828
[email protected]49639fa2011-12-20 23:22:414829 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:254830
[email protected]f3cf9802011-10-28 18:44:584831 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:414832 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:254833 EXPECT_EQ(ERR_IO_PENDING, rv);
4834
4835 rv = callback2.WaitForResult();
4836 EXPECT_EQ(OK, rv);
4837
4838 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4839
4840 response = trans->GetResponseInfo();
4841 ASSERT_TRUE(response != NULL);
[email protected]10af5fe72011-01-31 16:17:254842 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4843
[email protected]49639fa2011-12-20 23:22:414844 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:244845
[email protected]49639fa2011-12-20 23:22:414846 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:424847 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:244848
[email protected]0757e7702009-03-27 04:00:224849 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:424850 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:244851
4852 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:504853 ASSERT_TRUE(response != NULL);
[email protected]3f918782009-02-28 01:29:244854 EXPECT_TRUE(response->auth_challenge.get() == NULL);
4855 EXPECT_EQ(13, response->headers->GetContentLength());
4856}
4857
[email protected]385a4672009-03-11 22:21:294858// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:024859TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:424860 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:294861 request.method = "GET";
4862 request.url = GURL("http://172.22.68.17/kids/login.aspx");
4863 request.load_flags = 0;
4864
[email protected]cb9bf6ca2011-01-28 13:15:274865 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
4866 MockGetHostName);
[email protected]bb88e1d32013-05-03 23:11:074867 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:274868
[email protected]385a4672009-03-11 22:21:294869 MockWrite data_writes1[] = {
4870 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4871 "Host: 172.22.68.17\r\n"
4872 "Connection: keep-alive\r\n\r\n"),
4873 };
4874
4875 MockRead data_reads1[] = {
4876 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:044877 // Negotiate and NTLM are often requested together. However, we only want
4878 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
4879 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:294880 MockRead("WWW-Authenticate: NTLM\r\n"),
4881 MockRead("Connection: close\r\n"),
4882 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364883 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294884 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064885 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294886 };
4887
4888 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:224889 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294890 // request we should be issuing -- the final header line contains a Type
4891 // 1 message.
4892 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4893 "Host: 172.22.68.17\r\n"
4894 "Connection: keep-alive\r\n"
4895 "Authorization: NTLM "
4896 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4897
4898 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4899 // (the credentials for the origin server). The second request continues
4900 // on the same connection.
4901 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4902 "Host: 172.22.68.17\r\n"
4903 "Connection: keep-alive\r\n"
4904 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4905 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4906 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
4907 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
4908 "4Ww7b7E=\r\n\r\n"),
4909 };
4910
4911 MockRead data_reads2[] = {
4912 // The origin server responds with a Type 2 message.
4913 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4914 MockRead("WWW-Authenticate: NTLM "
4915 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
4916 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4917 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4918 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4919 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4920 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4921 "BtAAAAAAA=\r\n"),
4922 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364923 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294924 MockRead("You are not authorized to view this page\r\n"),
4925
4926 // Wrong password.
4927 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:294928 MockRead("WWW-Authenticate: NTLM\r\n"),
4929 MockRead("Connection: close\r\n"),
4930 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364931 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294932 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:064933 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:294934 };
4935
4936 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:224937 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:294938 // request we should be issuing -- the final header line contains a Type
4939 // 1 message.
4940 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4941 "Host: 172.22.68.17\r\n"
4942 "Connection: keep-alive\r\n"
4943 "Authorization: NTLM "
4944 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
4945
4946 // After calling trans->RestartWithAuth(), we should send a Type 3 message
4947 // (the credentials for the origin server). The second request continues
4948 // on the same connection.
4949 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
4950 "Host: 172.22.68.17\r\n"
4951 "Connection: keep-alive\r\n"
4952 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
4953 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
4954 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
4955 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
4956 "+4MUm7c=\r\n\r\n"),
4957 };
4958
4959 MockRead data_reads3[] = {
4960 // The origin server responds with a Type 2 message.
4961 MockRead("HTTP/1.1 401 Access Denied\r\n"),
4962 MockRead("WWW-Authenticate: NTLM "
4963 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
4964 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
4965 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
4966 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
4967 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
4968 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
4969 "BtAAAAAAA=\r\n"),
4970 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:364971 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:294972 MockRead("You are not authorized to view this page\r\n"),
4973
4974 // Lastly we get the desired content.
4975 MockRead("HTTP/1.1 200 OK\r\n"),
4976 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
4977 MockRead("Content-Length: 13\r\n\r\n"),
4978 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:064979 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:294980 };
4981
[email protected]31a2bfe2010-02-09 08:03:394982 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4983 data_writes1, arraysize(data_writes1));
4984 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4985 data_writes2, arraysize(data_writes2));
4986 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
4987 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:074988 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4989 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4990 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:294991
[email protected]49639fa2011-12-20 23:22:414992 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:294993
[email protected]262eec82013-03-19 21:01:364994 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504995 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504996
[email protected]49639fa2011-12-20 23:22:414997 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:424998 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:294999
5000 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425001 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:295002
[email protected]0757e7702009-03-27 04:00:225003 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:295004
[email protected]1c773ea12009-04-28 19:58:425005 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505006 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045007 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:295008
[email protected]49639fa2011-12-20 23:22:415009 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:295010
[email protected]0757e7702009-03-27 04:00:225011 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:585012 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:415013 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425014 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:295015
[email protected]10af5fe72011-01-31 16:17:255016 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425017 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:295018
[email protected]0757e7702009-03-27 04:00:225019 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:415020 TestCompletionCallback callback3;
5021 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425022 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:255023 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425024 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225025 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5026
5027 response = trans->GetResponseInfo();
[email protected]79cb5c12011-09-12 13:12:045028 ASSERT_FALSE(response == NULL);
5029 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:225030
[email protected]49639fa2011-12-20 23:22:415031 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:225032
5033 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:585034 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:415035 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:255036 EXPECT_EQ(ERR_IO_PENDING, rv);
5037
5038 rv = callback4.WaitForResult();
5039 EXPECT_EQ(OK, rv);
5040
5041 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5042
[email protected]49639fa2011-12-20 23:22:415043 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:255044
5045 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:415046 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:425047 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:225048
5049 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425050 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225051
[email protected]385a4672009-03-11 22:21:295052 response = trans->GetResponseInfo();
5053 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5054 EXPECT_EQ(13, response->headers->GetContentLength());
5055}
[email protected]ea9dc9a2009-09-05 00:43:325056#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:295057
[email protected]4ddaf2502008-10-23 18:26:195058// Test reading a server response which has only headers, and no body.
5059// After some maximum number of bytes is consumed, the transaction should
5060// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:025061TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:425062 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:195063 request.method = "GET";
bncce36dca22015-04-21 22:11:235064 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:195065 request.load_flags = 0;
5066
[email protected]3fe8d2f82013-10-17 08:56:075067 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275068 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415069 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275070
[email protected]b75b7b2f2009-10-06 00:54:535071 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:435072 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:535073 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:195074
5075 MockRead data_reads[] = {
5076 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:065077 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:195078 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:065079 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:195080 };
[email protected]31a2bfe2010-02-09 08:03:395081 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075082 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:195083
[email protected]49639fa2011-12-20 23:22:415084 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:195085
[email protected]49639fa2011-12-20 23:22:415086 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425087 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:195088
5089 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425090 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:195091}
[email protected]f4e426b2008-11-05 00:24:495092
5093// Make sure that we don't try to reuse a TCPClientSocket when failing to
5094// establish tunnel.
5095// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:025096TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:235097 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:275098 HttpRequestInfo request;
5099 request.method = "GET";
bncce36dca22015-04-21 22:11:235100 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275101 request.load_flags = 0;
5102
[email protected]f4e426b2008-11-05 00:24:495103 // Configure against proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:075104 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]db8f44c2008-12-13 04:52:015105
[email protected]bb88e1d32013-05-03 23:11:075106 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:495107
[email protected]262eec82013-03-19 21:01:365108 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505109 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:495110
[email protected]f4e426b2008-11-05 00:24:495111 // Since we have proxy, should try to establish tunnel.
5112 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235113 MockWrite(
5114 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5115 "Host: www.example.org\r\n"
5116 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:495117 };
5118
[email protected]77848d12008-11-14 00:00:225119 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:495120 // connection. Usually a proxy would return 501 (not implemented),
5121 // or 200 (tunnel established).
5122 MockRead data_reads1[] = {
5123 MockRead("HTTP/1.1 404 Not Found\r\n"),
5124 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065125 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
[email protected]f4e426b2008-11-05 00:24:495126 };
5127
[email protected]31a2bfe2010-02-09 08:03:395128 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5129 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075130 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:495131
[email protected]49639fa2011-12-20 23:22:415132 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:495133
[email protected]49639fa2011-12-20 23:22:415134 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425135 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:495136
5137 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425138 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:495139
[email protected]b4404c02009-04-10 16:38:525140 // Empty the current queue. This is necessary because idle sockets are
5141 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345142 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525143
[email protected]f4e426b2008-11-05 00:24:495144 // We now check to make sure the TCPClientSocket was not added back to
5145 // the pool.
[email protected]90499482013-06-01 00:39:505146 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495147 trans.reset();
[email protected]2da659e2013-05-23 20:51:345148 base::MessageLoop::current()->RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:495149 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:505150 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:495151}
[email protected]372d34a2008-11-05 21:30:515152
[email protected]1b157c02009-04-21 01:55:405153// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:025154TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:425155 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:405156 request.method = "GET";
bncce36dca22015-04-21 22:11:235157 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:405158 request.load_flags = 0;
5159
[email protected]bb88e1d32013-05-03 23:11:075160 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275161
[email protected]262eec82013-03-19 21:01:365162 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505163 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275164
[email protected]1b157c02009-04-21 01:55:405165 MockRead data_reads[] = {
5166 // A part of the response body is received with the response headers.
5167 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
5168 // The rest of the response body is received in two parts.
5169 MockRead("lo"),
5170 MockRead(" world"),
5171 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065172 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:405173 };
5174
[email protected]31a2bfe2010-02-09 08:03:395175 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075176 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:405177
[email protected]49639fa2011-12-20 23:22:415178 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:405179
[email protected]49639fa2011-12-20 23:22:415180 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425181 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:405182
5183 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425184 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405185
[email protected]1c773ea12009-04-28 19:58:425186 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505187 ASSERT_TRUE(response != NULL);
[email protected]1b157c02009-04-21 01:55:405188
[email protected]90499482013-06-01 00:39:505189 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]1b157c02009-04-21 01:55:405190 std::string status_line = response->headers->GetStatusLine();
5191 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
5192
[email protected]90499482013-06-01 00:39:505193 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405194
5195 std::string response_data;
5196 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425197 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:405198 EXPECT_EQ("hello world", response_data);
5199
5200 // Empty the current queue. This is necessary because idle sockets are
5201 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345202 base::MessageLoop::current()->RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:405203
5204 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505205 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:405206}
5207
[email protected]76a505b2010-08-25 06:23:005208// Make sure that we recycle a SSL socket after reading all of the response
5209// body.
[email protected]23e482282013-06-14 16:08:025210TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005211 HttpRequestInfo request;
5212 request.method = "GET";
bncce36dca22015-04-21 22:11:235213 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005214 request.load_flags = 0;
5215
5216 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235217 MockWrite(
5218 "GET / HTTP/1.1\r\n"
5219 "Host: www.example.org\r\n"
5220 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005221 };
5222
5223 MockRead data_reads[] = {
5224 MockRead("HTTP/1.1 200 OK\r\n"),
5225 MockRead("Content-Length: 11\r\n\r\n"),
5226 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065227 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:005228 };
5229
[email protected]8ddf8322012-02-23 18:08:065230 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075231 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:005232
5233 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5234 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075235 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:005236
[email protected]49639fa2011-12-20 23:22:415237 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005238
[email protected]bb88e1d32013-05-03 23:11:075239 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365240 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505241 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005242
[email protected]49639fa2011-12-20 23:22:415243 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005244
5245 EXPECT_EQ(ERR_IO_PENDING, rv);
5246 EXPECT_EQ(OK, callback.WaitForResult());
5247
5248 const HttpResponseInfo* response = trans->GetResponseInfo();
5249 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505250 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005251 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5252
[email protected]90499482013-06-01 00:39:505253 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005254
5255 std::string response_data;
5256 rv = ReadTransaction(trans.get(), &response_data);
5257 EXPECT_EQ(OK, rv);
5258 EXPECT_EQ("hello world", response_data);
5259
5260 // Empty the current queue. This is necessary because idle sockets are
5261 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345262 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005263
5264 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505265 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005266}
5267
5268// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
5269// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:025270TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:005271 HttpRequestInfo request;
5272 request.method = "GET";
bncce36dca22015-04-21 22:11:235273 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:005274 request.load_flags = 0;
5275
5276 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:235277 MockWrite(
5278 "GET / HTTP/1.1\r\n"
5279 "Host: www.example.org\r\n"
5280 "Connection: keep-alive\r\n\r\n"),
5281 MockWrite(
5282 "GET / HTTP/1.1\r\n"
5283 "Host: www.example.org\r\n"
5284 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:005285 };
5286
5287 MockRead data_reads[] = {
5288 MockRead("HTTP/1.1 200 OK\r\n"),
5289 MockRead("Content-Length: 11\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065290 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:005291 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065292 MockRead(ASYNC, 0, 0) // EOF
[email protected]76a505b2010-08-25 06:23:005293 };
5294
[email protected]8ddf8322012-02-23 18:08:065295 SSLSocketDataProvider ssl(ASYNC, OK);
5296 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075297 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5298 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:005299
5300 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5301 data_writes, arraysize(data_writes));
5302 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
5303 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075304 session_deps_.socket_factory->AddSocketDataProvider(&data);
5305 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:005306
[email protected]49639fa2011-12-20 23:22:415307 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:005308
[email protected]bb88e1d32013-05-03 23:11:075309 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:365310 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505311 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005312
[email protected]49639fa2011-12-20 23:22:415313 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005314
5315 EXPECT_EQ(ERR_IO_PENDING, rv);
5316 EXPECT_EQ(OK, callback.WaitForResult());
5317
5318 const HttpResponseInfo* response = trans->GetResponseInfo();
5319 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505320 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005321 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5322
[email protected]90499482013-06-01 00:39:505323 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005324
5325 std::string response_data;
5326 rv = ReadTransaction(trans.get(), &response_data);
5327 EXPECT_EQ(OK, rv);
5328 EXPECT_EQ("hello world", response_data);
5329
5330 // Empty the current queue. This is necessary because idle sockets are
5331 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345332 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005333
5334 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505335 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005336
5337 // Now start the second transaction, which should reuse the previous socket.
5338
[email protected]90499482013-06-01 00:39:505339 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:005340
[email protected]49639fa2011-12-20 23:22:415341 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:005342
5343 EXPECT_EQ(ERR_IO_PENDING, rv);
5344 EXPECT_EQ(OK, callback.WaitForResult());
5345
5346 response = trans->GetResponseInfo();
5347 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:505348 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]76a505b2010-08-25 06:23:005349 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5350
[email protected]90499482013-06-01 00:39:505351 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005352
5353 rv = ReadTransaction(trans.get(), &response_data);
5354 EXPECT_EQ(OK, rv);
5355 EXPECT_EQ("hello world", response_data);
5356
5357 // Empty the current queue. This is necessary because idle sockets are
5358 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345359 base::MessageLoop::current()->RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:005360
5361 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505362 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:005363}
5364
[email protected]b4404c02009-04-10 16:38:525365// Make sure that we recycle a socket after a zero-length response.
5366// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:025367TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:425368 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:525369 request.method = "GET";
bncce36dca22015-04-21 22:11:235370 request.url = GURL(
5371 "http://www.example.org/csi?v=3&s=web&action=&"
5372 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
5373 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
5374 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:525375 request.load_flags = 0;
5376
[email protected]bb88e1d32013-05-03 23:11:075377 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275378
[email protected]262eec82013-03-19 21:01:365379 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505380 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275381
[email protected]b4404c02009-04-10 16:38:525382 MockRead data_reads[] = {
5383 MockRead("HTTP/1.1 204 No Content\r\n"
5384 "Content-Length: 0\r\n"
5385 "Content-Type: text/html\r\n\r\n"),
5386 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:065387 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:525388 };
5389
[email protected]31a2bfe2010-02-09 08:03:395390 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:075391 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:525392
[email protected]49639fa2011-12-20 23:22:415393 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:525394
[email protected]49639fa2011-12-20 23:22:415395 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425396 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:525397
5398 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425399 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525400
[email protected]1c773ea12009-04-28 19:58:425401 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505402 ASSERT_TRUE(response != NULL);
[email protected]b4404c02009-04-10 16:38:525403
[email protected]90499482013-06-01 00:39:505404 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]b4404c02009-04-10 16:38:525405 std::string status_line = response->headers->GetStatusLine();
5406 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
5407
[email protected]90499482013-06-01 00:39:505408 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525409
5410 std::string response_data;
5411 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425412 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:525413 EXPECT_EQ("", response_data);
5414
5415 // Empty the current queue. This is necessary because idle sockets are
5416 // added to the connection pool asynchronously with a PostTask.
[email protected]2da659e2013-05-23 20:51:345417 base::MessageLoop::current()->RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:525418
5419 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:505420 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:525421}
5422
[email protected]23e482282013-06-14 16:08:025423TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
[email protected]b2d26cfd2012-12-11 10:36:065424 ScopedVector<UploadElementReader> element_readers;
5425 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:075426 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:275427
[email protected]1c773ea12009-04-28 19:58:425428 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:515429 // Transaction 1: a GET request that succeeds. The socket is recycled
5430 // after use.
5431 request[0].method = "GET";
5432 request[0].url = GURL("http://www.google.com/");
5433 request[0].load_flags = 0;
5434 // Transaction 2: a POST request. Reuses the socket kept alive from
5435 // transaction 1. The first attempts fails when writing the POST data.
5436 // This causes the transaction to retry with a new socket. The second
5437 // attempt succeeds.
5438 request[1].method = "POST";
5439 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:275440 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:515441 request[1].load_flags = 0;
5442
[email protected]bb88e1d32013-05-03 23:11:075443 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:515444
5445 // The first socket is used for transaction 1 and the first attempt of
5446 // transaction 2.
5447
5448 // The response of transaction 1.
5449 MockRead data_reads1[] = {
5450 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
5451 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:065452 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515453 };
5454 // The mock write results of transaction 1 and the first attempt of
5455 // transaction 2.
5456 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:065457 MockWrite(SYNCHRONOUS, 64), // GET
5458 MockWrite(SYNCHRONOUS, 93), // POST
5459 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:515460 };
[email protected]31a2bfe2010-02-09 08:03:395461 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5462 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:515463
5464 // The second socket is used for the second attempt of transaction 2.
5465
5466 // The response of transaction 2.
5467 MockRead data_reads2[] = {
5468 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
5469 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:065470 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:515471 };
5472 // The mock write results of the second attempt of transaction 2.
5473 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:065474 MockWrite(SYNCHRONOUS, 93), // POST
5475 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:515476 };
[email protected]31a2bfe2010-02-09 08:03:395477 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5478 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:515479
[email protected]bb88e1d32013-05-03 23:11:075480 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5481 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:515482
thestig9d3bb0c2015-01-24 00:49:515483 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:515484 "hello world", "welcome"
5485 };
5486
5487 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:425488 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505489 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:515490
[email protected]49639fa2011-12-20 23:22:415491 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:515492
[email protected]49639fa2011-12-20 23:22:415493 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425494 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:515495
5496 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425497 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515498
[email protected]1c773ea12009-04-28 19:58:425499 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505500 ASSERT_TRUE(response != NULL);
[email protected]372d34a2008-11-05 21:30:515501
[email protected]90499482013-06-01 00:39:505502 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]372d34a2008-11-05 21:30:515503 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5504
5505 std::string response_data;
5506 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:425507 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:515508 EXPECT_EQ(kExpectedResponseData[i], response_data);
5509 }
5510}
[email protected]f9ee6b52008-11-08 06:46:235511
5512// Test the request-challenge-retry sequence for basic auth when there is
5513// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:165514// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:025515TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:425516 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235517 request.method = "GET";
bncce36dca22015-04-21 22:11:235518 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:415519 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:295520
[email protected]3fe8d2f82013-10-17 08:56:075521 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275522 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415523 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275524
[email protected]a97cca42009-08-14 01:00:295525 // The password contains an escaped character -- for this test to pass it
5526 // will need to be unescaped by HttpNetworkTransaction.
5527 EXPECT_EQ("b%40r", request.url.password());
5528
[email protected]f9ee6b52008-11-08 06:46:235529 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235530 MockWrite(
5531 "GET / HTTP/1.1\r\n"
5532 "Host: www.example.org\r\n"
5533 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235534 };
5535
5536 MockRead data_reads1[] = {
5537 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5538 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5539 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065540 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235541 };
5542
[email protected]2262e3a2012-05-22 16:08:165543 // After the challenge above, the transaction will be restarted using the
5544 // identity from the url (foo, b@r) to answer the challenge.
5545 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235546 MockWrite(
5547 "GET / HTTP/1.1\r\n"
5548 "Host: www.example.org\r\n"
5549 "Connection: keep-alive\r\n"
5550 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165551 };
5552
5553 MockRead data_reads2[] = {
5554 MockRead("HTTP/1.0 200 OK\r\n"),
5555 MockRead("Content-Length: 100\r\n\r\n"),
5556 MockRead(SYNCHRONOUS, OK),
5557 };
5558
[email protected]31a2bfe2010-02-09 08:03:395559 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5560 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:165561 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5562 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075563 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5564 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235565
[email protected]49639fa2011-12-20 23:22:415566 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:415567 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425568 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235569 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425570 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:165571 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5572
5573 TestCompletionCallback callback2;
5574 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5575 EXPECT_EQ(ERR_IO_PENDING, rv);
5576 rv = callback2.WaitForResult();
5577 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:225578 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5579
[email protected]2262e3a2012-05-22 16:08:165580 const HttpResponseInfo* response = trans->GetResponseInfo();
5581 ASSERT_TRUE(response != NULL);
5582
5583 // There is no challenge info, since the identity in URL worked.
5584 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5585
5586 EXPECT_EQ(100, response->headers->GetContentLength());
5587
5588 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345589 base::MessageLoop::current()->RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:165590}
5591
5592// Test the request-challenge-retry sequence for basic auth when there is an
5593// incorrect identity in the URL. The identity from the URL should be used only
5594// once.
[email protected]23e482282013-06-14 16:08:025595TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:165596 HttpRequestInfo request;
5597 request.method = "GET";
5598 // Note: the URL has a username:password in it. The password "baz" is
5599 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:235600 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:165601
5602 request.load_flags = LOAD_NORMAL;
5603
[email protected]3fe8d2f82013-10-17 08:56:075604 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2262e3a2012-05-22 16:08:165605 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415606 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:165607
5608 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235609 MockWrite(
5610 "GET / HTTP/1.1\r\n"
5611 "Host: www.example.org\r\n"
5612 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165613 };
5614
5615 MockRead data_reads1[] = {
5616 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5617 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5618 MockRead("Content-Length: 10\r\n\r\n"),
5619 MockRead(SYNCHRONOUS, ERR_FAILED),
5620 };
5621
5622 // After the challenge above, the transaction will be restarted using the
5623 // identity from the url (foo, baz) to answer the challenge.
5624 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235625 MockWrite(
5626 "GET / HTTP/1.1\r\n"
5627 "Host: www.example.org\r\n"
5628 "Connection: keep-alive\r\n"
5629 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165630 };
5631
5632 MockRead data_reads2[] = {
5633 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5634 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5635 MockRead("Content-Length: 10\r\n\r\n"),
5636 MockRead(SYNCHRONOUS, ERR_FAILED),
5637 };
5638
5639 // After the challenge above, the transaction will be restarted using the
5640 // identity supplied by the user (foo, bar) to answer the challenge.
5641 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235642 MockWrite(
5643 "GET / HTTP/1.1\r\n"
5644 "Host: www.example.org\r\n"
5645 "Connection: keep-alive\r\n"
5646 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:165647 };
5648
5649 MockRead data_reads3[] = {
5650 MockRead("HTTP/1.0 200 OK\r\n"),
5651 MockRead("Content-Length: 100\r\n\r\n"),
5652 MockRead(SYNCHRONOUS, OK),
5653 };
5654
5655 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5656 data_writes1, arraysize(data_writes1));
5657 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5658 data_writes2, arraysize(data_writes2));
5659 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5660 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075661 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5662 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5663 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:165664
5665 TestCompletionCallback callback1;
5666
5667 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5668 EXPECT_EQ(ERR_IO_PENDING, rv);
5669
5670 rv = callback1.WaitForResult();
5671 EXPECT_EQ(OK, rv);
5672
5673 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5674 TestCompletionCallback callback2;
5675 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
5676 EXPECT_EQ(ERR_IO_PENDING, rv);
5677 rv = callback2.WaitForResult();
5678 EXPECT_EQ(OK, rv);
5679 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5680
5681 const HttpResponseInfo* response = trans->GetResponseInfo();
5682 ASSERT_TRUE(response != NULL);
5683 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5684
5685 TestCompletionCallback callback3;
5686 rv = trans->RestartWithAuth(
5687 AuthCredentials(kFoo, kBar), callback3.callback());
5688 EXPECT_EQ(ERR_IO_PENDING, rv);
5689 rv = callback3.WaitForResult();
5690 EXPECT_EQ(OK, rv);
5691 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5692
5693 response = trans->GetResponseInfo();
5694 ASSERT_TRUE(response != NULL);
5695
5696 // There is no challenge info, since the identity worked.
5697 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5698
5699 EXPECT_EQ(100, response->headers->GetContentLength());
5700
[email protected]ea9dc9a2009-09-05 00:43:325701 // Empty the current queue.
[email protected]2da659e2013-05-23 20:51:345702 base::MessageLoop::current()->RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:325703}
5704
[email protected]2217aa22013-10-11 03:03:545705
5706// Test the request-challenge-retry sequence for basic auth when there is a
5707// correct identity in the URL, but its use is being suppressed. The identity
5708// from the URL should never be used.
5709TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
5710 HttpRequestInfo request;
5711 request.method = "GET";
bncce36dca22015-04-21 22:11:235712 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:545713 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
5714
[email protected]3fe8d2f82013-10-17 08:56:075715 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2217aa22013-10-11 03:03:545716 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415717 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:545718
5719 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235720 MockWrite(
5721 "GET / HTTP/1.1\r\n"
5722 "Host: www.example.org\r\n"
5723 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545724 };
5725
5726 MockRead data_reads1[] = {
5727 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5728 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5729 MockRead("Content-Length: 10\r\n\r\n"),
5730 MockRead(SYNCHRONOUS, ERR_FAILED),
5731 };
5732
5733 // After the challenge above, the transaction will be restarted using the
5734 // identity supplied by the user, not the one in the URL, to answer the
5735 // challenge.
5736 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235737 MockWrite(
5738 "GET / HTTP/1.1\r\n"
5739 "Host: www.example.org\r\n"
5740 "Connection: keep-alive\r\n"
5741 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:545742 };
5743
5744 MockRead data_reads3[] = {
5745 MockRead("HTTP/1.0 200 OK\r\n"),
5746 MockRead("Content-Length: 100\r\n\r\n"),
5747 MockRead(SYNCHRONOUS, OK),
5748 };
5749
5750 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5751 data_writes1, arraysize(data_writes1));
5752 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5753 data_writes3, arraysize(data_writes3));
5754 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5755 session_deps_.socket_factory->AddSocketDataProvider(&data3);
5756
5757 TestCompletionCallback callback1;
5758 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
5759 EXPECT_EQ(ERR_IO_PENDING, rv);
5760 rv = callback1.WaitForResult();
5761 EXPECT_EQ(OK, rv);
5762 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5763
5764 const HttpResponseInfo* response = trans->GetResponseInfo();
5765 ASSERT_TRUE(response != NULL);
5766 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
5767
5768 TestCompletionCallback callback3;
5769 rv = trans->RestartWithAuth(
5770 AuthCredentials(kFoo, kBar), callback3.callback());
5771 EXPECT_EQ(ERR_IO_PENDING, rv);
5772 rv = callback3.WaitForResult();
5773 EXPECT_EQ(OK, rv);
5774 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5775
5776 response = trans->GetResponseInfo();
5777 ASSERT_TRUE(response != NULL);
5778
5779 // There is no challenge info, since the identity worked.
5780 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5781 EXPECT_EQ(100, response->headers->GetContentLength());
5782
5783 // Empty the current queue.
5784 base::MessageLoop::current()->RunUntilIdle();
5785}
5786
[email protected]f9ee6b52008-11-08 06:46:235787// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:025788TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
[email protected]bb88e1d32013-05-03 23:11:075789 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:235790
5791 // Transaction 1: authenticate (foo, bar) on MyRealm1
5792 {
[email protected]1c773ea12009-04-28 19:58:425793 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235794 request.method = "GET";
bncce36dca22015-04-21 22:11:235795 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:235796 request.load_flags = 0;
5797
[email protected]262eec82013-03-19 21:01:365798 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505799 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275800
[email protected]f9ee6b52008-11-08 06:46:235801 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235802 MockWrite(
5803 "GET /x/y/z HTTP/1.1\r\n"
5804 "Host: www.example.org\r\n"
5805 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235806 };
5807
5808 MockRead data_reads1[] = {
5809 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5810 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5811 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065812 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235813 };
5814
5815 // Resend with authorization (username=foo, password=bar)
5816 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235817 MockWrite(
5818 "GET /x/y/z HTTP/1.1\r\n"
5819 "Host: www.example.org\r\n"
5820 "Connection: keep-alive\r\n"
5821 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235822 };
5823
5824 // Sever accepts the authorization.
5825 MockRead data_reads2[] = {
5826 MockRead("HTTP/1.0 200 OK\r\n"),
5827 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065828 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235829 };
5830
[email protected]31a2bfe2010-02-09 08:03:395831 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5832 data_writes1, arraysize(data_writes1));
5833 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5834 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075835 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5836 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235837
[email protected]49639fa2011-12-20 23:22:415838 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235839
[email protected]49639fa2011-12-20 23:22:415840 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425841 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235842
5843 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425844 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235845
[email protected]1c773ea12009-04-28 19:58:425846 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505847 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045848 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:235849
[email protected]49639fa2011-12-20 23:22:415850 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235851
[email protected]49639fa2011-12-20 23:22:415852 rv = trans->RestartWithAuth(
5853 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425854 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235855
5856 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425857 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235858
5859 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505860 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235861 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5862 EXPECT_EQ(100, response->headers->GetContentLength());
5863 }
5864
5865 // ------------------------------------------------------------------------
5866
5867 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
5868 {
[email protected]1c773ea12009-04-28 19:58:425869 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235870 request.method = "GET";
5871 // Note that Transaction 1 was at /x/y/z, so this is in the same
5872 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:235873 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:235874 request.load_flags = 0;
5875
[email protected]262eec82013-03-19 21:01:365876 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505877 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275878
[email protected]f9ee6b52008-11-08 06:46:235879 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235880 MockWrite(
5881 "GET /x/y/a/b HTTP/1.1\r\n"
5882 "Host: www.example.org\r\n"
5883 "Connection: keep-alive\r\n"
5884 // Send preemptive authorization for MyRealm1
5885 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235886 };
5887
5888 // The server didn't like the preemptive authorization, and
5889 // challenges us for a different realm (MyRealm2).
5890 MockRead data_reads1[] = {
5891 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5892 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
5893 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065894 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:235895 };
5896
5897 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
5898 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235899 MockWrite(
5900 "GET /x/y/a/b HTTP/1.1\r\n"
5901 "Host: www.example.org\r\n"
5902 "Connection: keep-alive\r\n"
5903 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235904 };
5905
5906 // Sever accepts the authorization.
5907 MockRead data_reads2[] = {
5908 MockRead("HTTP/1.0 200 OK\r\n"),
5909 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065910 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235911 };
5912
[email protected]31a2bfe2010-02-09 08:03:395913 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5914 data_writes1, arraysize(data_writes1));
5915 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5916 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075917 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5918 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:235919
[email protected]49639fa2011-12-20 23:22:415920 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235921
[email protected]49639fa2011-12-20 23:22:415922 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425923 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235924
5925 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425926 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235927
[email protected]1c773ea12009-04-28 19:58:425928 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505929 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:045930 ASSERT_TRUE(response->auth_challenge.get());
5931 EXPECT_FALSE(response->auth_challenge->is_proxy);
bncce36dca22015-04-21 22:11:235932 EXPECT_EQ("www.example.org:80",
[email protected]79cb5c12011-09-12 13:12:045933 response->auth_challenge->challenger.ToString());
5934 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
5935 EXPECT_EQ("basic", response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:235936
[email protected]49639fa2011-12-20 23:22:415937 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:235938
[email protected]49639fa2011-12-20 23:22:415939 rv = trans->RestartWithAuth(
5940 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425941 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235942
5943 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425944 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235945
5946 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505947 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235948 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5949 EXPECT_EQ(100, response->headers->GetContentLength());
5950 }
5951
5952 // ------------------------------------------------------------------------
5953
5954 // Transaction 3: Resend a request in MyRealm's protection space --
5955 // succeed with preemptive authorization.
5956 {
[email protected]1c773ea12009-04-28 19:58:425957 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:235958 request.method = "GET";
bncce36dca22015-04-21 22:11:235959 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:235960 request.load_flags = 0;
5961
[email protected]262eec82013-03-19 21:01:365962 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505963 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:275964
[email protected]f9ee6b52008-11-08 06:46:235965 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235966 MockWrite(
5967 "GET /x/y/z2 HTTP/1.1\r\n"
5968 "Host: www.example.org\r\n"
5969 "Connection: keep-alive\r\n"
5970 // The authorization for MyRealm1 gets sent preemptively
5971 // (since the url is in the same protection space)
5972 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235973 };
5974
5975 // Sever accepts the preemptive authorization
5976 MockRead data_reads1[] = {
5977 MockRead("HTTP/1.0 200 OK\r\n"),
5978 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065979 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:235980 };
5981
[email protected]31a2bfe2010-02-09 08:03:395982 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5983 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075984 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:235985
[email protected]49639fa2011-12-20 23:22:415986 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:235987
[email protected]49639fa2011-12-20 23:22:415988 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425989 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:235990
5991 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425992 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:235993
[email protected]1c773ea12009-04-28 19:58:425994 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:505995 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:235996
5997 EXPECT_TRUE(response->auth_challenge.get() == NULL);
5998 EXPECT_EQ(100, response->headers->GetContentLength());
5999 }
6000
6001 // ------------------------------------------------------------------------
6002
6003 // Transaction 4: request another URL in MyRealm (however the
6004 // url is not known to belong to the protection space, so no pre-auth).
6005 {
[email protected]1c773ea12009-04-28 19:58:426006 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236007 request.method = "GET";
bncce36dca22015-04-21 22:11:236008 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:236009 request.load_flags = 0;
6010
[email protected]262eec82013-03-19 21:01:366011 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506012 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276013
[email protected]f9ee6b52008-11-08 06:46:236014 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236015 MockWrite(
6016 "GET /x/1 HTTP/1.1\r\n"
6017 "Host: www.example.org\r\n"
6018 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236019 };
6020
6021 MockRead data_reads1[] = {
6022 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6023 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6024 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066025 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236026 };
6027
6028 // Resend with authorization from MyRealm's cache.
6029 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236030 MockWrite(
6031 "GET /x/1 HTTP/1.1\r\n"
6032 "Host: www.example.org\r\n"
6033 "Connection: keep-alive\r\n"
6034 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236035 };
6036
6037 // Sever accepts the authorization.
6038 MockRead data_reads2[] = {
6039 MockRead("HTTP/1.0 200 OK\r\n"),
6040 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066041 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236042 };
6043
[email protected]31a2bfe2010-02-09 08:03:396044 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6045 data_writes1, arraysize(data_writes1));
6046 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6047 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076048 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6049 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236050
[email protected]49639fa2011-12-20 23:22:416051 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236052
[email protected]49639fa2011-12-20 23:22:416053 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426054 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236055
6056 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426057 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236058
[email protected]0757e7702009-03-27 04:00:226059 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416060 TestCompletionCallback callback2;
6061 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426062 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226063 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426064 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226065 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6066
[email protected]1c773ea12009-04-28 19:58:426067 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506068 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236069 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6070 EXPECT_EQ(100, response->headers->GetContentLength());
6071 }
6072
6073 // ------------------------------------------------------------------------
6074
6075 // Transaction 5: request a URL in MyRealm, but the server rejects the
6076 // cached identity. Should invalidate and re-prompt.
6077 {
[email protected]1c773ea12009-04-28 19:58:426078 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236079 request.method = "GET";
bncce36dca22015-04-21 22:11:236080 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:236081 request.load_flags = 0;
6082
[email protected]262eec82013-03-19 21:01:366083 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506084 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276085
[email protected]f9ee6b52008-11-08 06:46:236086 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236087 MockWrite(
6088 "GET /p/q/t HTTP/1.1\r\n"
6089 "Host: www.example.org\r\n"
6090 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236091 };
6092
6093 MockRead data_reads1[] = {
6094 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6095 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6096 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066097 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236098 };
6099
6100 // Resend with authorization from cache for MyRealm.
6101 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236102 MockWrite(
6103 "GET /p/q/t HTTP/1.1\r\n"
6104 "Host: www.example.org\r\n"
6105 "Connection: keep-alive\r\n"
6106 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236107 };
6108
6109 // Sever rejects the authorization.
6110 MockRead data_reads2[] = {
6111 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6112 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6113 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066114 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236115 };
6116
6117 // At this point we should prompt for new credentials for MyRealm.
6118 // Restart with username=foo3, password=foo4.
6119 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236120 MockWrite(
6121 "GET /p/q/t HTTP/1.1\r\n"
6122 "Host: www.example.org\r\n"
6123 "Connection: keep-alive\r\n"
6124 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236125 };
6126
6127 // Sever accepts the authorization.
6128 MockRead data_reads3[] = {
6129 MockRead("HTTP/1.0 200 OK\r\n"),
6130 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066131 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236132 };
6133
[email protected]31a2bfe2010-02-09 08:03:396134 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6135 data_writes1, arraysize(data_writes1));
6136 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6137 data_writes2, arraysize(data_writes2));
6138 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6139 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076140 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6141 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6142 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:236143
[email protected]49639fa2011-12-20 23:22:416144 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236145
[email protected]49639fa2011-12-20 23:22:416146 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426147 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236148
6149 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426150 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236151
[email protected]0757e7702009-03-27 04:00:226152 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416153 TestCompletionCallback callback2;
6154 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426155 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226156 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426157 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226158 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6159
[email protected]1c773ea12009-04-28 19:58:426160 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506161 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046162 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236163
[email protected]49639fa2011-12-20 23:22:416164 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:236165
[email protected]49639fa2011-12-20 23:22:416166 rv = trans->RestartWithAuth(
6167 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426168 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236169
[email protected]0757e7702009-03-27 04:00:226170 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426171 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236172
6173 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506174 ASSERT_TRUE(response != NULL);
[email protected]f9ee6b52008-11-08 06:46:236175 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6176 EXPECT_EQ(100, response->headers->GetContentLength());
6177 }
6178}
[email protected]89ceba9a2009-03-21 03:46:066179
[email protected]3c32c5f2010-05-18 15:18:126180// Tests that nonce count increments when multiple auth attempts
6181// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:026182TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:446183 HttpAuthHandlerDigest::Factory* digest_factory =
6184 new HttpAuthHandlerDigest::Factory();
6185 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
6186 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
6187 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:076188 session_deps_.http_auth_handler_factory.reset(digest_factory);
6189 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:126190
6191 // Transaction 1: authenticate (foo, bar) on MyRealm1
6192 {
[email protected]3c32c5f2010-05-18 15:18:126193 HttpRequestInfo request;
6194 request.method = "GET";
bncce36dca22015-04-21 22:11:236195 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:126196 request.load_flags = 0;
6197
[email protected]262eec82013-03-19 21:01:366198 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506199 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276200
[email protected]3c32c5f2010-05-18 15:18:126201 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236202 MockWrite(
6203 "GET /x/y/z HTTP/1.1\r\n"
6204 "Host: www.example.org\r\n"
6205 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126206 };
6207
6208 MockRead data_reads1[] = {
6209 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6210 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
6211 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066212 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126213 };
6214
6215 // Resend with authorization (username=foo, password=bar)
6216 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236217 MockWrite(
6218 "GET /x/y/z HTTP/1.1\r\n"
6219 "Host: www.example.org\r\n"
6220 "Connection: keep-alive\r\n"
6221 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6222 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
6223 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
6224 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126225 };
6226
6227 // Sever accepts the authorization.
6228 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:086229 MockRead("HTTP/1.0 200 OK\r\n"),
6230 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126231 };
6232
6233 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6234 data_writes1, arraysize(data_writes1));
6235 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6236 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076237 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6238 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:126239
[email protected]49639fa2011-12-20 23:22:416240 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126241
[email protected]49639fa2011-12-20 23:22:416242 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126243 EXPECT_EQ(ERR_IO_PENDING, rv);
6244
6245 rv = callback1.WaitForResult();
6246 EXPECT_EQ(OK, rv);
6247
6248 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506249 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:046250 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:126251
[email protected]49639fa2011-12-20 23:22:416252 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:126253
[email protected]49639fa2011-12-20 23:22:416254 rv = trans->RestartWithAuth(
6255 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:126256 EXPECT_EQ(ERR_IO_PENDING, rv);
6257
6258 rv = callback2.WaitForResult();
6259 EXPECT_EQ(OK, rv);
6260
6261 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506262 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126263 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6264 }
6265
6266 // ------------------------------------------------------------------------
6267
6268 // Transaction 2: Request another resource in digestive's protection space.
6269 // This will preemptively add an Authorization header which should have an
6270 // "nc" value of 2 (as compared to 1 in the first use.
6271 {
[email protected]3c32c5f2010-05-18 15:18:126272 HttpRequestInfo request;
6273 request.method = "GET";
6274 // Note that Transaction 1 was at /x/y/z, so this is in the same
6275 // protection space as digest.
bncce36dca22015-04-21 22:11:236276 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:126277 request.load_flags = 0;
6278
[email protected]262eec82013-03-19 21:01:366279 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506280 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276281
[email protected]3c32c5f2010-05-18 15:18:126282 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236283 MockWrite(
6284 "GET /x/y/a/b HTTP/1.1\r\n"
6285 "Host: www.example.org\r\n"
6286 "Connection: keep-alive\r\n"
6287 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
6288 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
6289 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
6290 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:126291 };
6292
6293 // Sever accepts the authorization.
6294 MockRead data_reads1[] = {
6295 MockRead("HTTP/1.0 200 OK\r\n"),
6296 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066297 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:126298 };
6299
6300 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6301 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076302 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:126303
[email protected]49639fa2011-12-20 23:22:416304 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:126305
[email protected]49639fa2011-12-20 23:22:416306 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:126307 EXPECT_EQ(ERR_IO_PENDING, rv);
6308
6309 rv = callback1.WaitForResult();
6310 EXPECT_EQ(OK, rv);
6311
6312 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:506313 ASSERT_TRUE(response != NULL);
[email protected]3c32c5f2010-05-18 15:18:126314 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6315 }
6316}
6317
[email protected]89ceba9a2009-03-21 03:46:066318// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:026319TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:066320 // Create a transaction (the dependencies aren't important).
[email protected]3fe8d2f82013-10-17 08:56:076321 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406322 scoped_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:416323 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:066324
6325 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:066326 trans->read_buf_ = new IOBuffer(15);
6327 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:206328 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:066329
6330 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:146331 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:576332 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:086333 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:576334 response->response_time = base::Time::Now();
6335 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:066336
6337 { // Setup state for response_.vary_data
6338 HttpRequestInfo request;
6339 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
6340 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:276341 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:436342 request.extra_headers.SetHeader("Foo", "1");
6343 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:506344 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:066345 }
6346
6347 // Cause the above state to be reset.
6348 trans->ResetStateForRestart();
6349
6350 // Verify that the state that needed to be reset, has been reset.
[email protected]9b6fee12009-09-29 18:13:076351 EXPECT_TRUE(trans->read_buf_.get() == NULL);
[email protected]89ceba9a2009-03-21 03:46:066352 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:206353 EXPECT_TRUE(trans->request_headers_.IsEmpty());
[email protected]0877e3d2009-10-17 22:29:576354 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6355 EXPECT_TRUE(response->headers.get() == NULL);
[email protected]34f40942010-10-04 00:34:046356 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:086357 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:576358 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:066359}
6360
[email protected]bacff652009-03-31 17:50:336361// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:026362TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:336363 HttpRequestInfo request;
6364 request.method = "GET";
bncce36dca22015-04-21 22:11:236365 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336366 request.load_flags = 0;
6367
[email protected]3fe8d2f82013-10-17 08:56:076368 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276369 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416370 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276371
[email protected]bacff652009-03-31 17:50:336372 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236373 MockWrite(
6374 "GET / HTTP/1.1\r\n"
6375 "Host: www.example.org\r\n"
6376 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336377 };
6378
6379 MockRead data_reads[] = {
6380 MockRead("HTTP/1.0 200 OK\r\n"),
6381 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6382 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066383 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336384 };
6385
[email protected]5ecc992a42009-11-11 01:41:596386 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:396387 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6388 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066389 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6390 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336391
[email protected]bb88e1d32013-05-03 23:11:076392 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6393 session_deps_.socket_factory->AddSocketDataProvider(&data);
6394 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6395 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336396
[email protected]49639fa2011-12-20 23:22:416397 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336398
[email protected]49639fa2011-12-20 23:22:416399 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336400 EXPECT_EQ(ERR_IO_PENDING, rv);
6401
6402 rv = callback.WaitForResult();
6403 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6404
[email protected]49639fa2011-12-20 23:22:416405 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336406 EXPECT_EQ(ERR_IO_PENDING, rv);
6407
6408 rv = callback.WaitForResult();
6409 EXPECT_EQ(OK, rv);
6410
6411 const HttpResponseInfo* response = trans->GetResponseInfo();
6412
[email protected]fe2255a2011-09-20 19:37:506413 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336414 EXPECT_EQ(100, response->headers->GetContentLength());
6415}
6416
6417// Test HTTPS connections to a site with a bad certificate, going through a
6418// proxy
[email protected]23e482282013-06-14 16:08:026419TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
[email protected]bb88e1d32013-05-03 23:11:076420 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]bacff652009-03-31 17:50:336421
6422 HttpRequestInfo request;
6423 request.method = "GET";
bncce36dca22015-04-21 22:11:236424 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:336425 request.load_flags = 0;
6426
6427 MockWrite proxy_writes[] = {
bncce36dca22015-04-21 22:11:236428 MockWrite(
6429 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6430 "Host: www.example.org\r\n"
6431 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336432 };
6433
6434 MockRead proxy_reads[] = {
6435 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066436 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:336437 };
6438
6439 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236440 MockWrite(
6441 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6442 "Host: www.example.org\r\n"
6443 "Proxy-Connection: keep-alive\r\n\r\n"),
6444 MockWrite(
6445 "GET / HTTP/1.1\r\n"
6446 "Host: www.example.org\r\n"
6447 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:336448 };
6449
6450 MockRead data_reads[] = {
6451 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6452 MockRead("HTTP/1.0 200 OK\r\n"),
6453 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6454 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066455 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:336456 };
6457
[email protected]31a2bfe2010-02-09 08:03:396458 StaticSocketDataProvider ssl_bad_certificate(
6459 proxy_reads, arraysize(proxy_reads),
6460 proxy_writes, arraysize(proxy_writes));
6461 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6462 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066463 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
6464 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:336465
[email protected]bb88e1d32013-05-03 23:11:076466 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
6467 session_deps_.socket_factory->AddSocketDataProvider(&data);
6468 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
6469 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:336470
[email protected]49639fa2011-12-20 23:22:416471 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:336472
6473 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:076474 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:336475
[email protected]3fe8d2f82013-10-17 08:56:076476 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d207a5f2009-06-04 05:28:406477 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416478 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:336479
[email protected]49639fa2011-12-20 23:22:416480 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:336481 EXPECT_EQ(ERR_IO_PENDING, rv);
6482
6483 rv = callback.WaitForResult();
6484 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
6485
[email protected]49639fa2011-12-20 23:22:416486 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:336487 EXPECT_EQ(ERR_IO_PENDING, rv);
6488
6489 rv = callback.WaitForResult();
6490 EXPECT_EQ(OK, rv);
6491
6492 const HttpResponseInfo* response = trans->GetResponseInfo();
6493
[email protected]fe2255a2011-09-20 19:37:506494 ASSERT_TRUE(response != NULL);
[email protected]bacff652009-03-31 17:50:336495 EXPECT_EQ(100, response->headers->GetContentLength());
6496 }
6497}
6498
[email protected]2df19bb2010-08-25 20:13:466499
6500// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:026501TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076502 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206503 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:516504 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076505 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:466506
6507 HttpRequestInfo request;
6508 request.method = "GET";
bncce36dca22015-04-21 22:11:236509 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466510 request.load_flags = 0;
6511
6512 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236513 MockWrite(
6514 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6515 "Host: www.example.org\r\n"
6516 "Proxy-Connection: keep-alive\r\n\r\n"),
6517 MockWrite(
6518 "GET / HTTP/1.1\r\n"
6519 "Host: www.example.org\r\n"
6520 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466521 };
6522
6523 MockRead data_reads[] = {
6524 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
6525 MockRead("HTTP/1.1 200 OK\r\n"),
6526 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6527 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066528 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466529 };
6530
6531 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6532 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066533 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
6534 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:466535
[email protected]bb88e1d32013-05-03 23:11:076536 session_deps_.socket_factory->AddSocketDataProvider(&data);
6537 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
6538 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:466539
[email protected]49639fa2011-12-20 23:22:416540 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:466541
[email protected]3fe8d2f82013-10-17 08:56:076542 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:466543 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416544 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:466545
[email protected]49639fa2011-12-20 23:22:416546 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:466547 EXPECT_EQ(ERR_IO_PENDING, rv);
6548
6549 rv = callback.WaitForResult();
6550 EXPECT_EQ(OK, rv);
6551 const HttpResponseInfo* response = trans->GetResponseInfo();
6552
[email protected]fe2255a2011-09-20 19:37:506553 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:466554
6555 EXPECT_TRUE(response->headers->IsKeepAlive());
6556 EXPECT_EQ(200, response->headers->response_code());
6557 EXPECT_EQ(100, response->headers->GetContentLength());
6558 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:206559
6560 LoadTimingInfo load_timing_info;
6561 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6562 TestLoadTimingNotReusedWithPac(load_timing_info,
6563 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:466564}
6565
[email protected]511f6f52010-12-17 03:58:296566// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026567TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076568 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206569 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:516570 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:076571 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:296572
6573 HttpRequestInfo request;
6574 request.method = "GET";
bncce36dca22015-04-21 22:11:236575 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296576 request.load_flags = 0;
6577
6578 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236579 MockWrite(
6580 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6581 "Host: www.example.org\r\n"
6582 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296583 };
6584
6585 MockRead data_reads[] = {
6586 MockRead("HTTP/1.1 302 Redirect\r\n"),
6587 MockRead("Location: http://login.example.com/\r\n"),
6588 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066589 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296590 };
6591
6592 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6593 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066594 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296595
[email protected]bb88e1d32013-05-03 23:11:076596 session_deps_.socket_factory->AddSocketDataProvider(&data);
6597 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296598
[email protected]49639fa2011-12-20 23:22:416599 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296600
[email protected]3fe8d2f82013-10-17 08:56:076601 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296602 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416603 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296604
[email protected]49639fa2011-12-20 23:22:416605 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296606 EXPECT_EQ(ERR_IO_PENDING, rv);
6607
6608 rv = callback.WaitForResult();
6609 EXPECT_EQ(OK, rv);
6610 const HttpResponseInfo* response = trans->GetResponseInfo();
6611
[email protected]fe2255a2011-09-20 19:37:506612 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296613
6614 EXPECT_EQ(302, response->headers->response_code());
6615 std::string url;
6616 EXPECT_TRUE(response->headers->IsRedirect(&url));
6617 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:206618
6619 // In the case of redirects from proxies, HttpNetworkTransaction returns
6620 // timing for the proxy connection instead of the connection to the host,
6621 // and no send / receive times.
6622 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
6623 LoadTimingInfo load_timing_info;
6624 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6625
6626 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:296627 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:206628
6629 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
6630 EXPECT_LE(load_timing_info.proxy_resolve_start,
6631 load_timing_info.proxy_resolve_end);
6632 EXPECT_LE(load_timing_info.proxy_resolve_end,
6633 load_timing_info.connect_timing.connect_start);
6634 ExpectConnectTimingHasTimes(
6635 load_timing_info.connect_timing,
6636 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
6637
6638 EXPECT_TRUE(load_timing_info.send_start.is_null());
6639 EXPECT_TRUE(load_timing_info.send_end.is_null());
6640 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:296641}
6642
6643// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:026644TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076645 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296646 ProxyService::CreateFixed("https://proxy:70"));
6647
6648 HttpRequestInfo request;
6649 request.method = "GET";
bncce36dca22015-04-21 22:11:236650 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296651 request.load_flags = 0;
6652
lgarrona91df87f2014-12-05 00:51:346653 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236654 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206655 scoped_ptr<SpdyFrame> goaway(
6656 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296657 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136658 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
6659 CreateMockWrite(*goaway.get(), 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:296660 };
6661
6662 static const char* const kExtraHeaders[] = {
6663 "location",
6664 "http://login.example.com/",
6665 };
[email protected]ff98d7f02012-03-22 21:44:196666 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026667 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296668 arraysize(kExtraHeaders)/2, 1));
6669 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136670 CreateMockRead(*resp.get(), 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:296671 };
6672
rch8e6c6c42015-05-01 14:05:136673 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6674 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066675 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026676 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296677
[email protected]bb88e1d32013-05-03 23:11:076678 session_deps_.socket_factory->AddSocketDataProvider(&data);
6679 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296680
[email protected]49639fa2011-12-20 23:22:416681 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296682
[email protected]3fe8d2f82013-10-17 08:56:076683 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296684 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416685 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296686
[email protected]49639fa2011-12-20 23:22:416687 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296688 EXPECT_EQ(ERR_IO_PENDING, rv);
6689
6690 rv = callback.WaitForResult();
6691 EXPECT_EQ(OK, rv);
6692 const HttpResponseInfo* response = trans->GetResponseInfo();
6693
[email protected]fe2255a2011-09-20 19:37:506694 ASSERT_TRUE(response != NULL);
[email protected]511f6f52010-12-17 03:58:296695
6696 EXPECT_EQ(302, response->headers->response_code());
6697 std::string url;
6698 EXPECT_TRUE(response->headers->IsRedirect(&url));
6699 EXPECT_EQ("http://login.example.com/", url);
6700}
6701
[email protected]4eddbc732012-08-09 05:40:176702// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026703TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176704 ErrorResponseToHttpsConnectViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:076705 session_deps_.proxy_service.reset(
[email protected]511f6f52010-12-17 03:58:296706 ProxyService::CreateFixed("https://proxy:70"));
6707
6708 HttpRequestInfo request;
6709 request.method = "GET";
bncce36dca22015-04-21 22:11:236710 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296711 request.load_flags = 0;
6712
6713 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236714 MockWrite(
6715 "CONNECT www.example.org:443 HTTP/1.1\r\n"
6716 "Host: www.example.org\r\n"
6717 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:296718 };
6719
6720 MockRead data_reads[] = {
6721 MockRead("HTTP/1.1 404 Not Found\r\n"),
6722 MockRead("Content-Length: 23\r\n\r\n"),
6723 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:066724 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:296725 };
6726
6727 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6728 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066729 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:296730
[email protected]bb88e1d32013-05-03 23:11:076731 session_deps_.socket_factory->AddSocketDataProvider(&data);
6732 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296733
[email protected]49639fa2011-12-20 23:22:416734 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296735
[email protected]3fe8d2f82013-10-17 08:56:076736 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296737 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416738 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296739
[email protected]49639fa2011-12-20 23:22:416740 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296741 EXPECT_EQ(ERR_IO_PENDING, rv);
6742
6743 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176744 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296745
[email protected]4eddbc732012-08-09 05:40:176746 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296747}
6748
[email protected]4eddbc732012-08-09 05:40:176749// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:026750TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:176751 ErrorResponseToHttpsConnectViaSpdyProxy) {
[email protected]bb88e1d32013-05-03 23:11:076752 session_deps_.proxy_service.reset(
6753 ProxyService::CreateFixed("https://proxy:70"));
[email protected]511f6f52010-12-17 03:58:296754
6755 HttpRequestInfo request;
6756 request.method = "GET";
bncce36dca22015-04-21 22:11:236757 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:296758 request.load_flags = 0;
6759
lgarrona91df87f2014-12-05 00:51:346760 scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236761 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206762 scoped_ptr<SpdyFrame> rst(
6763 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:296764 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:136765 CreateMockWrite(*conn.get(), 0), CreateMockWrite(*rst.get(), 3),
[email protected]511f6f52010-12-17 03:58:296766 };
6767
6768 static const char* const kExtraHeaders[] = {
6769 "location",
6770 "http://login.example.com/",
6771 };
[email protected]ff98d7f02012-03-22 21:44:196772 scoped_ptr<SpdyFrame> resp(
[email protected]23e482282013-06-14 16:08:026773 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
[email protected]511f6f52010-12-17 03:58:296774 arraysize(kExtraHeaders)/2, 1));
[email protected]ff98d7f02012-03-22 21:44:196775 scoped_ptr<SpdyFrame> body(
[email protected]23e482282013-06-14 16:08:026776 spdy_util_.ConstructSpdyBodyFrame(
6777 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:296778 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:136779 CreateMockRead(*resp.get(), 1),
6780 CreateMockRead(*body.get(), 2),
6781 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:296782 };
6783
rch8e6c6c42015-05-01 14:05:136784 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
6785 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:066786 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]23e482282013-06-14 16:08:026787 proxy_ssl.SetNextProto(GetParam());
[email protected]511f6f52010-12-17 03:58:296788
[email protected]bb88e1d32013-05-03 23:11:076789 session_deps_.socket_factory->AddSocketDataProvider(&data);
6790 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:296791
[email protected]49639fa2011-12-20 23:22:416792 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:296793
[email protected]3fe8d2f82013-10-17 08:56:076794 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]511f6f52010-12-17 03:58:296795 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416796 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:296797
[email protected]49639fa2011-12-20 23:22:416798 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:296799 EXPECT_EQ(ERR_IO_PENDING, rv);
6800
6801 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:176802 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:296803
[email protected]4eddbc732012-08-09 05:40:176804 // TODO(ttuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:296805}
6806
[email protected]0c5fb722012-02-28 11:50:356807// Test the request-challenge-retry sequence for basic auth, through
6808// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:026809TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:356810 HttpRequestInfo request;
6811 request.method = "GET";
bncce36dca22015-04-21 22:11:236812 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:356813 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296814 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:356815
6816 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076817 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206818 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516819 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076820 session_deps_.net_log = log.bound().net_log();
6821 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:356822
6823 // Since we have proxy, should try to establish tunnel.
lgarrona91df87f2014-12-05 00:51:346824 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:236825 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
[email protected]c10b20852013-05-15 21:29:206826 scoped_ptr<SpdyFrame> rst(
6827 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]0c5fb722012-02-28 11:50:356828
6829 // After calling trans->RestartWithAuth(), this is the request we should
6830 // be issuing -- the final header line contains the credentials.
6831 const char* const kAuthCredentials[] = {
6832 "proxy-authorization", "Basic Zm9vOmJhcg==",
6833 };
[email protected]fba2dbde2013-05-24 16:09:016834 scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:346835 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:236836 HostPortPair("www.example.org", 443)));
6837 // fetch https://www.example.org/ via HTTP
6838 const char get[] =
6839 "GET / HTTP/1.1\r\n"
6840 "Host: www.example.org\r\n"
6841 "Connection: keep-alive\r\n\r\n";
[email protected]ff98d7f02012-03-22 21:44:196842 scoped_ptr<SpdyFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:026843 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:356844
6845 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136846 CreateMockWrite(*req, 0, ASYNC),
6847 CreateMockWrite(*rst, 2, ASYNC),
6848 CreateMockWrite(*connect2, 3),
6849 CreateMockWrite(*wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:356850 };
6851
6852 // The proxy responds to the connect with a 407, using a persistent
6853 // connection.
thestig9d3bb0c2015-01-24 00:49:516854 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:356855 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:356856 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
6857 };
[email protected]745aa9c2014-06-27 02:21:296858 scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
6859 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:356860
[email protected]23e482282013-06-14 16:08:026861 scoped_ptr<SpdyFrame> conn_resp(
6862 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:356863 const char resp[] = "HTTP/1.1 200 OK\r\n"
6864 "Content-Length: 5\r\n\r\n";
6865
[email protected]ff98d7f02012-03-22 21:44:196866 scoped_ptr<SpdyFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:026867 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
[email protected]ff98d7f02012-03-22 21:44:196868 scoped_ptr<SpdyFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:026869 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:356870 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:136871 CreateMockRead(*conn_auth_resp, 1, ASYNC),
6872 CreateMockRead(*conn_resp, 4, ASYNC),
6873 CreateMockRead(*wrapped_get_resp, 6, ASYNC),
6874 CreateMockRead(*wrapped_body, 7, ASYNC),
6875 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:356876 };
6877
rch8e6c6c42015-05-01 14:05:136878 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
6879 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:076880 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:356881 // Negotiate SPDY to the proxy
6882 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:026883 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:076884 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:356885 // Vanilla SSL to the server
6886 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076887 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:356888
6889 TestCompletionCallback callback1;
6890
[email protected]262eec82013-03-19 21:01:366891 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506892 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:356893
6894 int rv = trans->Start(&request, callback1.callback(), log.bound());
6895 EXPECT_EQ(ERR_IO_PENDING, rv);
6896
6897 rv = callback1.WaitForResult();
6898 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:466899 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:356900 log.GetEntries(&entries);
6901 size_t pos = ExpectLogContainsSomewhere(
6902 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
6903 NetLog::PHASE_NONE);
6904 ExpectLogContainsSomewhere(
6905 entries, pos,
6906 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
6907 NetLog::PHASE_NONE);
6908
6909 const HttpResponseInfo* response = trans->GetResponseInfo();
6910 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:506911 ASSERT_FALSE(response->headers.get() == NULL);
[email protected]0c5fb722012-02-28 11:50:356912 EXPECT_EQ(407, response->headers->response_code());
6913 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6914 EXPECT_TRUE(response->auth_challenge.get() != NULL);
6915 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
6916
6917 TestCompletionCallback callback2;
6918
6919 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
6920 callback2.callback());
6921 EXPECT_EQ(ERR_IO_PENDING, rv);
6922
6923 rv = callback2.WaitForResult();
6924 EXPECT_EQ(OK, rv);
6925
6926 response = trans->GetResponseInfo();
6927 ASSERT_TRUE(response != NULL);
6928
6929 EXPECT_TRUE(response->headers->IsKeepAlive());
6930 EXPECT_EQ(200, response->headers->response_code());
6931 EXPECT_EQ(5, response->headers->GetContentLength());
6932 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
6933
6934 // The password prompt info should not be set.
6935 EXPECT_TRUE(response->auth_challenge.get() == NULL);
6936
[email protected]029c83b62013-01-24 05:28:206937 LoadTimingInfo load_timing_info;
6938 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6939 TestLoadTimingNotReusedWithPac(load_timing_info,
6940 CONNECT_TIMING_HAS_SSL_TIMES);
6941
[email protected]0c5fb722012-02-28 11:50:356942 trans.reset();
6943 session->CloseAllConnections();
6944}
6945
[email protected]7c6f7ba2012-04-03 04:09:296946// Test that an explicitly trusted SPDY proxy can push a resource from an
6947// origin that is different from that of its associated resource.
[email protected]23e482282013-06-14 16:08:026948TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
[email protected]7c6f7ba2012-04-03 04:09:296949 HttpRequestInfo request;
6950 HttpRequestInfo push_request;
6951
[email protected]7c6f7ba2012-04-03 04:09:296952 request.method = "GET";
bncce36dca22015-04-21 22:11:236953 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:296954 push_request.method = "GET";
6955 push_request.url = GURL("http://www.another-origin.com/foo.dat");
6956
[email protected]7c6f7ba2012-04-03 04:09:296957 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:076958 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:206959 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
vishal.b62985ca92015-04-17 08:45:516960 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076961 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:506962
6963 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:076964 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:506965
[email protected]bb88e1d32013-05-03 23:11:076966 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:296967
[email protected]cdf8f7e72013-05-23 10:56:466968 scoped_ptr<SpdyFrame> stream1_syn(
6969 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:296970
6971 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:136972 CreateMockWrite(*stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:296973 };
6974
6975 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026976 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:296977
6978 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026979 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:296980
6981 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:026982 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]7c6f7ba2012-04-03 04:09:296983 0,
6984 2,
6985 1,
6986 "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:436987 const char kPushedData[] = "pushed";
6988 scoped_ptr<SpdyFrame> stream2_body(
6989 spdy_util_.ConstructSpdyBodyFrame(
6990 2, kPushedData, strlen(kPushedData), true));
[email protected]7c6f7ba2012-04-03 04:09:296991
6992 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:136993 CreateMockRead(*stream1_reply, 1, ASYNC),
6994 CreateMockRead(*stream2_syn, 2, ASYNC),
6995 CreateMockRead(*stream1_body, 3, ASYNC),
6996 CreateMockRead(*stream2_body, 4, ASYNC),
6997 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]7c6f7ba2012-04-03 04:09:296998 };
6999
rch8e6c6c42015-05-01 14:05:137000 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7001 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077002 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:297003 // Negotiate SPDY to the proxy
7004 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027005 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077006 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:297007
[email protected]262eec82013-03-19 21:01:367008 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507009 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:297010 TestCompletionCallback callback;
7011 int rv = trans->Start(&request, callback.callback(), log.bound());
7012 EXPECT_EQ(ERR_IO_PENDING, rv);
7013
7014 rv = callback.WaitForResult();
7015 EXPECT_EQ(OK, rv);
7016 const HttpResponseInfo* response = trans->GetResponseInfo();
7017
[email protected]262eec82013-03-19 21:01:367018 scoped_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:507019 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
7020 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:297021 EXPECT_EQ(ERR_IO_PENDING, rv);
7022
7023 rv = callback.WaitForResult();
7024 EXPECT_EQ(OK, rv);
7025 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
7026
7027 ASSERT_TRUE(response != NULL);
7028 EXPECT_TRUE(response->headers->IsKeepAlive());
7029
7030 EXPECT_EQ(200, response->headers->response_code());
7031 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7032
7033 std::string response_data;
7034 rv = ReadTransaction(trans.get(), &response_data);
7035 EXPECT_EQ(OK, rv);
7036 EXPECT_EQ("hello!", response_data);
7037
[email protected]029c83b62013-01-24 05:28:207038 LoadTimingInfo load_timing_info;
7039 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7040 TestLoadTimingNotReusedWithPac(load_timing_info,
7041 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7042
[email protected]7c6f7ba2012-04-03 04:09:297043 // Verify the pushed stream.
[email protected]90499482013-06-01 00:39:507044 EXPECT_TRUE(push_response->headers.get() != NULL);
[email protected]7c6f7ba2012-04-03 04:09:297045 EXPECT_EQ(200, push_response->headers->response_code());
7046
7047 rv = ReadTransaction(push_trans.get(), &response_data);
7048 EXPECT_EQ(OK, rv);
7049 EXPECT_EQ("pushed", response_data);
7050
[email protected]029c83b62013-01-24 05:28:207051 LoadTimingInfo push_load_timing_info;
7052 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
7053 TestLoadTimingReusedWithPac(push_load_timing_info);
7054 // The transactions should share a socket ID, despite being for different
7055 // origins.
7056 EXPECT_EQ(load_timing_info.socket_log_id,
7057 push_load_timing_info.socket_log_id);
7058
[email protected]7c6f7ba2012-04-03 04:09:297059 trans.reset();
7060 push_trans.reset();
7061 session->CloseAllConnections();
7062}
7063
[email protected]8c843192012-04-05 07:15:007064// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:027065TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
[email protected]8c843192012-04-05 07:15:007066 HttpRequestInfo request;
7067
7068 request.method = "GET";
bncce36dca22015-04-21 22:11:237069 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:007070
[email protected]8c843192012-04-05 07:15:007071 // Configure against https proxy server "myproxy:70".
[email protected]bb88e1d32013-05-03 23:11:077072 session_deps_.proxy_service.reset(
[email protected]8c843192012-04-05 07:15:007073 ProxyService::CreateFixed("https://myproxy:70"));
vishal.b62985ca92015-04-17 08:45:517074 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077075 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:507076
7077 // Enable cross-origin push.
[email protected]bb88e1d32013-05-03 23:11:077078 session_deps_.trusted_spdy_proxy = "myproxy:70";
[email protected]61b4efc2012-04-27 18:12:507079
[email protected]bb88e1d32013-05-03 23:11:077080 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:007081
[email protected]cdf8f7e72013-05-23 10:56:467082 scoped_ptr<SpdyFrame> stream1_syn(
7083 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:007084
7085 scoped_ptr<SpdyFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:207086 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:007087
7088 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137089 CreateMockWrite(*stream1_syn, 0, ASYNC), CreateMockWrite(*push_rst, 3),
[email protected]8c843192012-04-05 07:15:007090 };
7091
7092 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027093 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:007094
7095 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027096 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:007097
7098 scoped_ptr<SpdyFrame>
[email protected]23e482282013-06-14 16:08:027099 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
[email protected]8c843192012-04-05 07:15:007100 0,
7101 2,
7102 1,
7103 "https://www.another-origin.com/foo.dat"));
7104
7105 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137106 CreateMockRead(*stream1_reply, 1, ASYNC),
7107 CreateMockRead(*stream2_syn, 2, ASYNC),
7108 CreateMockRead(*stream1_body, 4, ASYNC),
7109 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
[email protected]8c843192012-04-05 07:15:007110 };
7111
rch8e6c6c42015-05-01 14:05:137112 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7113 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077114 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:007115 // Negotiate SPDY to the proxy
7116 SSLSocketDataProvider proxy(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:027117 proxy.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:077118 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:007119
[email protected]262eec82013-03-19 21:01:367120 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507121 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:007122 TestCompletionCallback callback;
7123 int rv = trans->Start(&request, callback.callback(), log.bound());
7124 EXPECT_EQ(ERR_IO_PENDING, rv);
7125
7126 rv = callback.WaitForResult();
7127 EXPECT_EQ(OK, rv);
7128 const HttpResponseInfo* response = trans->GetResponseInfo();
7129
7130 ASSERT_TRUE(response != NULL);
7131 EXPECT_TRUE(response->headers->IsKeepAlive());
7132
7133 EXPECT_EQ(200, response->headers->response_code());
7134 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7135
7136 std::string response_data;
7137 rv = ReadTransaction(trans.get(), &response_data);
7138 EXPECT_EQ(OK, rv);
7139 EXPECT_EQ("hello!", response_data);
7140
7141 trans.reset();
7142 session->CloseAllConnections();
7143}
7144
[email protected]2df19bb2010-08-25 20:13:467145// Test HTTPS connections to a site with a bad certificate, going through an
7146// HTTPS proxy
[email protected]23e482282013-06-14 16:08:027147TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
[email protected]bb88e1d32013-05-03 23:11:077148 session_deps_.proxy_service.reset(ProxyService::CreateFixed(
[email protected]3912662a32011-10-04 00:51:117149 "https://proxy:70"));
[email protected]2df19bb2010-08-25 20:13:467150
7151 HttpRequestInfo request;
7152 request.method = "GET";
bncce36dca22015-04-21 22:11:237153 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467154 request.load_flags = 0;
7155
7156 // Attempt to fetch the URL from a server with a bad cert
7157 MockWrite bad_cert_writes[] = {
bncce36dca22015-04-21 22:11:237158 MockWrite(
7159 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7160 "Host: www.example.org\r\n"
7161 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467162 };
7163
7164 MockRead bad_cert_reads[] = {
7165 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067166 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:467167 };
7168
7169 // Attempt to fetch the URL with a good cert
7170 MockWrite good_data_writes[] = {
bncce36dca22015-04-21 22:11:237171 MockWrite(
7172 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7173 "Host: www.example.org\r\n"
7174 "Proxy-Connection: keep-alive\r\n\r\n"),
7175 MockWrite(
7176 "GET / HTTP/1.1\r\n"
7177 "Host: www.example.org\r\n"
7178 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467179 };
7180
7181 MockRead good_cert_reads[] = {
7182 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7183 MockRead("HTTP/1.0 200 OK\r\n"),
7184 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7185 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067186 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467187 };
7188
7189 StaticSocketDataProvider ssl_bad_certificate(
7190 bad_cert_reads, arraysize(bad_cert_reads),
7191 bad_cert_writes, arraysize(bad_cert_writes));
7192 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
7193 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:067194 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7195 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:467196
7197 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:077198 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7199 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7200 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:467201
7202 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:077203 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7204 session_deps_.socket_factory->AddSocketDataProvider(&data);
7205 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:467206
[email protected]49639fa2011-12-20 23:22:417207 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467208
[email protected]3fe8d2f82013-10-17 08:56:077209 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:467210 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417211 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467212
[email protected]49639fa2011-12-20 23:22:417213 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467214 EXPECT_EQ(ERR_IO_PENDING, rv);
7215
7216 rv = callback.WaitForResult();
7217 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7218
[email protected]49639fa2011-12-20 23:22:417219 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:467220 EXPECT_EQ(ERR_IO_PENDING, rv);
7221
7222 rv = callback.WaitForResult();
7223 EXPECT_EQ(OK, rv);
7224
7225 const HttpResponseInfo* response = trans->GetResponseInfo();
7226
[email protected]fe2255a2011-09-20 19:37:507227 ASSERT_TRUE(response != NULL);
[email protected]2df19bb2010-08-25 20:13:467228 EXPECT_EQ(100, response->headers->GetContentLength());
7229}
7230
[email protected]23e482282013-06-14 16:08:027231TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:427232 HttpRequestInfo request;
7233 request.method = "GET";
bncce36dca22015-04-21 22:11:237234 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437235 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7236 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:427237
[email protected]3fe8d2f82013-10-17 08:56:077238 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277239 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417240 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277241
[email protected]1c773ea12009-04-28 19:58:427242 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237243 MockWrite(
7244 "GET / HTTP/1.1\r\n"
7245 "Host: www.example.org\r\n"
7246 "Connection: keep-alive\r\n"
7247 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427248 };
7249
7250 // Lastly, the server responds with the actual content.
7251 MockRead data_reads[] = {
7252 MockRead("HTTP/1.0 200 OK\r\n"),
7253 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7254 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067255 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427256 };
7257
[email protected]31a2bfe2010-02-09 08:03:397258 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7259 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077260 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427261
[email protected]49639fa2011-12-20 23:22:417262 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427263
[email protected]49639fa2011-12-20 23:22:417264 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427265 EXPECT_EQ(ERR_IO_PENDING, rv);
7266
7267 rv = callback.WaitForResult();
7268 EXPECT_EQ(OK, rv);
7269}
7270
[email protected]23e482282013-06-14 16:08:027271TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:297272 HttpRequestInfo request;
7273 request.method = "GET";
bncce36dca22015-04-21 22:11:237274 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:297275 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
7276 "Chromium Ultra Awesome X Edition");
7277
[email protected]bb88e1d32013-05-03 23:11:077278 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]3fe8d2f82013-10-17 08:56:077279 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277280 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417281 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277282
[email protected]da81f132010-08-18 23:39:297283 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237284 MockWrite(
7285 "CONNECT www.example.org:443 HTTP/1.1\r\n"
7286 "Host: www.example.org\r\n"
7287 "Proxy-Connection: keep-alive\r\n"
7288 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:297289 };
7290 MockRead data_reads[] = {
7291 // Return an error, so the transaction stops here (this test isn't
7292 // interested in the rest).
7293 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
7294 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7295 MockRead("Proxy-Connection: close\r\n\r\n"),
7296 };
7297
7298 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7299 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077300 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:297301
[email protected]49639fa2011-12-20 23:22:417302 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:297303
[email protected]49639fa2011-12-20 23:22:417304 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:297305 EXPECT_EQ(ERR_IO_PENDING, rv);
7306
7307 rv = callback.WaitForResult();
7308 EXPECT_EQ(OK, rv);
7309}
7310
[email protected]23e482282013-06-14 16:08:027311TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:427312 HttpRequestInfo request;
7313 request.method = "GET";
bncce36dca22015-04-21 22:11:237314 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427315 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:167316 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
7317 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:427318
[email protected]3fe8d2f82013-10-17 08:56:077319 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277320 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417321 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277322
[email protected]1c773ea12009-04-28 19:58:427323 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237324 MockWrite(
7325 "GET / HTTP/1.1\r\n"
7326 "Host: www.example.org\r\n"
7327 "Connection: keep-alive\r\n"
7328 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427329 };
7330
7331 // Lastly, the server responds with the actual content.
7332 MockRead data_reads[] = {
7333 MockRead("HTTP/1.0 200 OK\r\n"),
7334 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7335 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067336 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427337 };
7338
[email protected]31a2bfe2010-02-09 08:03:397339 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7340 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077341 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427342
[email protected]49639fa2011-12-20 23:22:417343 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427344
[email protected]49639fa2011-12-20 23:22:417345 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427346 EXPECT_EQ(ERR_IO_PENDING, rv);
7347
7348 rv = callback.WaitForResult();
7349 EXPECT_EQ(OK, rv);
7350}
7351
[email protected]23e482282013-06-14 16:08:027352TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427353 HttpRequestInfo request;
7354 request.method = "POST";
bncce36dca22015-04-21 22:11:237355 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427356
[email protected]3fe8d2f82013-10-17 08:56:077357 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277358 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417359 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277360
[email protected]1c773ea12009-04-28 19:58:427361 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237362 MockWrite(
7363 "POST / HTTP/1.1\r\n"
7364 "Host: www.example.org\r\n"
7365 "Connection: keep-alive\r\n"
7366 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427367 };
7368
7369 // Lastly, the server responds with the actual content.
7370 MockRead data_reads[] = {
7371 MockRead("HTTP/1.0 200 OK\r\n"),
7372 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7373 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067374 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427375 };
7376
[email protected]31a2bfe2010-02-09 08:03:397377 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7378 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077379 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427380
[email protected]49639fa2011-12-20 23:22:417381 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427382
[email protected]49639fa2011-12-20 23:22:417383 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427384 EXPECT_EQ(ERR_IO_PENDING, rv);
7385
7386 rv = callback.WaitForResult();
7387 EXPECT_EQ(OK, rv);
7388}
7389
[email protected]23e482282013-06-14 16:08:027390TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427391 HttpRequestInfo request;
7392 request.method = "PUT";
bncce36dca22015-04-21 22:11:237393 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427394
[email protected]3fe8d2f82013-10-17 08:56:077395 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277396 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417397 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277398
[email protected]1c773ea12009-04-28 19:58:427399 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237400 MockWrite(
7401 "PUT / HTTP/1.1\r\n"
7402 "Host: www.example.org\r\n"
7403 "Connection: keep-alive\r\n"
7404 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427405 };
7406
7407 // Lastly, the server responds with the actual content.
7408 MockRead data_reads[] = {
7409 MockRead("HTTP/1.0 200 OK\r\n"),
7410 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7411 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067412 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427413 };
7414
[email protected]31a2bfe2010-02-09 08:03:397415 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7416 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077417 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427418
[email protected]49639fa2011-12-20 23:22:417419 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427420
[email protected]49639fa2011-12-20 23:22:417421 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427422 EXPECT_EQ(ERR_IO_PENDING, rv);
7423
7424 rv = callback.WaitForResult();
7425 EXPECT_EQ(OK, rv);
7426}
7427
[email protected]23e482282013-06-14 16:08:027428TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:427429 HttpRequestInfo request;
7430 request.method = "HEAD";
bncce36dca22015-04-21 22:11:237431 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427432
[email protected]3fe8d2f82013-10-17 08:56:077433 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277434 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417435 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277436
[email protected]1c773ea12009-04-28 19:58:427437 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:137438 MockWrite("HEAD / HTTP/1.1\r\n"
7439 "Host: www.example.org\r\n"
7440 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427441 };
7442
7443 // Lastly, the server responds with the actual content.
7444 MockRead data_reads[] = {
7445 MockRead("HTTP/1.0 200 OK\r\n"),
7446 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7447 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067448 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427449 };
7450
[email protected]31a2bfe2010-02-09 08:03:397451 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7452 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077453 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427454
[email protected]49639fa2011-12-20 23:22:417455 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427456
[email protected]49639fa2011-12-20 23:22:417457 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427458 EXPECT_EQ(ERR_IO_PENDING, rv);
7459
7460 rv = callback.WaitForResult();
7461 EXPECT_EQ(OK, rv);
7462}
7463
[email protected]23e482282013-06-14 16:08:027464TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:427465 HttpRequestInfo request;
7466 request.method = "GET";
bncce36dca22015-04-21 22:11:237467 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427468 request.load_flags = LOAD_BYPASS_CACHE;
7469
[email protected]3fe8d2f82013-10-17 08:56:077470 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277471 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417472 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277473
[email protected]1c773ea12009-04-28 19:58:427474 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237475 MockWrite(
7476 "GET / HTTP/1.1\r\n"
7477 "Host: www.example.org\r\n"
7478 "Connection: keep-alive\r\n"
7479 "Pragma: no-cache\r\n"
7480 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427481 };
7482
7483 // Lastly, the server responds with the actual content.
7484 MockRead data_reads[] = {
7485 MockRead("HTTP/1.0 200 OK\r\n"),
7486 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7487 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067488 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427489 };
7490
[email protected]31a2bfe2010-02-09 08:03:397491 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7492 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077493 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427494
[email protected]49639fa2011-12-20 23:22:417495 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427496
[email protected]49639fa2011-12-20 23:22:417497 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427498 EXPECT_EQ(ERR_IO_PENDING, rv);
7499
7500 rv = callback.WaitForResult();
7501 EXPECT_EQ(OK, rv);
7502}
7503
[email protected]23e482282013-06-14 16:08:027504TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:427505 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:427506 HttpRequestInfo request;
7507 request.method = "GET";
bncce36dca22015-04-21 22:11:237508 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:427509 request.load_flags = LOAD_VALIDATE_CACHE;
7510
[email protected]3fe8d2f82013-10-17 08:56:077511 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277512 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417513 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277514
[email protected]1c773ea12009-04-28 19:58:427515 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237516 MockWrite(
7517 "GET / HTTP/1.1\r\n"
7518 "Host: www.example.org\r\n"
7519 "Connection: keep-alive\r\n"
7520 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427521 };
7522
7523 // Lastly, the server responds with the actual content.
7524 MockRead data_reads[] = {
7525 MockRead("HTTP/1.0 200 OK\r\n"),
7526 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7527 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067528 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427529 };
7530
[email protected]31a2bfe2010-02-09 08:03:397531 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7532 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077533 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427534
[email protected]49639fa2011-12-20 23:22:417535 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427536
[email protected]49639fa2011-12-20 23:22:417537 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427538 EXPECT_EQ(ERR_IO_PENDING, rv);
7539
7540 rv = callback.WaitForResult();
7541 EXPECT_EQ(OK, rv);
7542}
7543
[email protected]23e482282013-06-14 16:08:027544TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:427545 HttpRequestInfo request;
7546 request.method = "GET";
bncce36dca22015-04-21 22:11:237547 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437548 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:427549
[email protected]3fe8d2f82013-10-17 08:56:077550 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277551 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417552 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277553
[email protected]1c773ea12009-04-28 19:58:427554 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237555 MockWrite(
7556 "GET / HTTP/1.1\r\n"
7557 "Host: www.example.org\r\n"
7558 "Connection: keep-alive\r\n"
7559 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:427560 };
7561
7562 // Lastly, the server responds with the actual content.
7563 MockRead data_reads[] = {
7564 MockRead("HTTP/1.0 200 OK\r\n"),
7565 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7566 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067567 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:427568 };
7569
[email protected]31a2bfe2010-02-09 08:03:397570 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7571 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077572 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:427573
[email protected]49639fa2011-12-20 23:22:417574 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:427575
[email protected]49639fa2011-12-20 23:22:417576 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427577 EXPECT_EQ(ERR_IO_PENDING, rv);
7578
7579 rv = callback.WaitForResult();
7580 EXPECT_EQ(OK, rv);
7581}
7582
[email protected]23e482282013-06-14 16:08:027583TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:477584 HttpRequestInfo request;
7585 request.method = "GET";
bncce36dca22015-04-21 22:11:237586 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:437587 request.extra_headers.SetHeader("referer", "www.foo.com");
7588 request.extra_headers.SetHeader("hEllo", "Kitty");
7589 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:477590
[email protected]3fe8d2f82013-10-17 08:56:077591 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277592 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417593 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277594
[email protected]270c6412010-03-29 22:02:477595 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237596 MockWrite(
7597 "GET / HTTP/1.1\r\n"
7598 "Host: www.example.org\r\n"
7599 "Connection: keep-alive\r\n"
7600 "referer: www.foo.com\r\n"
7601 "hEllo: Kitty\r\n"
7602 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:477603 };
7604
7605 // Lastly, the server responds with the actual content.
7606 MockRead data_reads[] = {
7607 MockRead("HTTP/1.0 200 OK\r\n"),
7608 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7609 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067610 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:477611 };
7612
7613 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7614 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077615 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:477616
[email protected]49639fa2011-12-20 23:22:417617 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:477618
[email protected]49639fa2011-12-20 23:22:417619 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:477620 EXPECT_EQ(ERR_IO_PENDING, rv);
7621
7622 rv = callback.WaitForResult();
7623 EXPECT_EQ(OK, rv);
7624}
7625
[email protected]23e482282013-06-14 16:08:027626TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277627 HttpRequestInfo request;
7628 request.method = "GET";
bncce36dca22015-04-21 22:11:237629 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277630 request.load_flags = 0;
7631
[email protected]bb88e1d32013-05-03 23:11:077632 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207633 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517634 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077635 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027636
[email protected]3fe8d2f82013-10-17 08:56:077637 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027638 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417639 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027640
[email protected]3cd17242009-06-23 02:59:027641 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7642 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7643
7644 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237645 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7646 MockWrite(
7647 "GET / HTTP/1.1\r\n"
7648 "Host: www.example.org\r\n"
7649 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027650
7651 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:067652 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:027653 MockRead("HTTP/1.0 200 OK\r\n"),
7654 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7655 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067656 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027657 };
7658
[email protected]31a2bfe2010-02-09 08:03:397659 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7660 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077661 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027662
[email protected]49639fa2011-12-20 23:22:417663 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027664
[email protected]49639fa2011-12-20 23:22:417665 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027666 EXPECT_EQ(ERR_IO_PENDING, rv);
7667
7668 rv = callback.WaitForResult();
7669 EXPECT_EQ(OK, rv);
7670
7671 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507672 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027673
[email protected]029c83b62013-01-24 05:28:207674 LoadTimingInfo load_timing_info;
7675 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7676 TestLoadTimingNotReusedWithPac(load_timing_info,
7677 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7678
[email protected]3cd17242009-06-23 02:59:027679 std::string response_text;
7680 rv = ReadTransaction(trans.get(), &response_text);
7681 EXPECT_EQ(OK, rv);
7682 EXPECT_EQ("Payload", response_text);
7683}
7684
[email protected]23e482282013-06-14 16:08:027685TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277686 HttpRequestInfo request;
7687 request.method = "GET";
bncce36dca22015-04-21 22:11:237688 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277689 request.load_flags = 0;
7690
[email protected]bb88e1d32013-05-03 23:11:077691 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207692 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517693 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077694 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:027695
[email protected]3fe8d2f82013-10-17 08:56:077696 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3cd17242009-06-23 02:59:027697 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417698 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:027699
[email protected]3cd17242009-06-23 02:59:027700 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
7701 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7702
7703 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237704 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
7705 arraysize(write_buffer)),
7706 MockWrite(
7707 "GET / HTTP/1.1\r\n"
7708 "Host: www.example.org\r\n"
7709 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:027710
7711 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017712 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
7713 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:357714 MockRead("HTTP/1.0 200 OK\r\n"),
7715 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7716 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067717 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357718 };
7719
[email protected]31a2bfe2010-02-09 08:03:397720 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7721 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077722 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357723
[email protected]8ddf8322012-02-23 18:08:067724 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077725 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:357726
[email protected]49639fa2011-12-20 23:22:417727 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357728
[email protected]49639fa2011-12-20 23:22:417729 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357730 EXPECT_EQ(ERR_IO_PENDING, rv);
7731
7732 rv = callback.WaitForResult();
7733 EXPECT_EQ(OK, rv);
7734
[email protected]029c83b62013-01-24 05:28:207735 LoadTimingInfo load_timing_info;
7736 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7737 TestLoadTimingNotReusedWithPac(load_timing_info,
7738 CONNECT_TIMING_HAS_SSL_TIMES);
7739
[email protected]e0c27be2009-07-15 13:09:357740 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507741 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357742
7743 std::string response_text;
7744 rv = ReadTransaction(trans.get(), &response_text);
7745 EXPECT_EQ(OK, rv);
7746 EXPECT_EQ("Payload", response_text);
7747}
7748
[email protected]23e482282013-06-14 16:08:027749TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:207750 HttpRequestInfo request;
7751 request.method = "GET";
bncce36dca22015-04-21 22:11:237752 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:207753 request.load_flags = 0;
7754
[email protected]bb88e1d32013-05-03 23:11:077755 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207756 ProxyService::CreateFixed("socks4://myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517757 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077758 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:207759
[email protected]3fe8d2f82013-10-17 08:56:077760 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:207761 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417762 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:207763
7764 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
7765 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
7766
7767 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237768 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
7769 MockWrite(
7770 "GET / HTTP/1.1\r\n"
7771 "Host: www.example.org\r\n"
7772 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:207773
7774 MockRead data_reads[] = {
7775 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
7776 MockRead("HTTP/1.0 200 OK\r\n"),
7777 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7778 MockRead("Payload"),
7779 MockRead(SYNCHRONOUS, OK)
7780 };
7781
7782 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7783 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077784 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:207785
7786 TestCompletionCallback callback;
7787
7788 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
7789 EXPECT_EQ(ERR_IO_PENDING, rv);
7790
7791 rv = callback.WaitForResult();
7792 EXPECT_EQ(OK, rv);
7793
7794 const HttpResponseInfo* response = trans->GetResponseInfo();
7795 ASSERT_TRUE(response != NULL);
7796
7797 LoadTimingInfo load_timing_info;
7798 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7799 TestLoadTimingNotReused(load_timing_info,
7800 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7801
7802 std::string response_text;
7803 rv = ReadTransaction(trans.get(), &response_text);
7804 EXPECT_EQ(OK, rv);
7805 EXPECT_EQ("Payload", response_text);
7806}
7807
[email protected]23e482282013-06-14 16:08:027808TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277809 HttpRequestInfo request;
7810 request.method = "GET";
bncce36dca22015-04-21 22:11:237811 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277812 request.load_flags = 0;
7813
[email protected]bb88e1d32013-05-03 23:11:077814 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207815 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517816 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077817 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357818
[email protected]3fe8d2f82013-10-17 08:56:077819 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357820 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417821 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357822
[email protected]e0c27be2009-07-15 13:09:357823 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7824 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377825 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237826 0x05, // Version
7827 0x01, // Command (CONNECT)
7828 0x00, // Reserved.
7829 0x03, // Address type (DOMAINNAME).
7830 0x0F, // Length of domain (15)
7831 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7832 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:377833 };
[email protected]e0c27be2009-07-15 13:09:357834 const char kSOCKS5OkResponse[] =
7835 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
7836
7837 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237838 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7839 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
7840 MockWrite(
7841 "GET / HTTP/1.1\r\n"
7842 "Host: www.example.org\r\n"
7843 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357844
7845 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017846 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7847 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:357848 MockRead("HTTP/1.0 200 OK\r\n"),
7849 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7850 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067851 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:357852 };
7853
[email protected]31a2bfe2010-02-09 08:03:397854 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7855 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077856 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:357857
[email protected]49639fa2011-12-20 23:22:417858 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:357859
[email protected]49639fa2011-12-20 23:22:417860 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:357861 EXPECT_EQ(ERR_IO_PENDING, rv);
7862
7863 rv = callback.WaitForResult();
7864 EXPECT_EQ(OK, rv);
7865
7866 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507867 ASSERT_TRUE(response != NULL);
[email protected]e0c27be2009-07-15 13:09:357868
[email protected]029c83b62013-01-24 05:28:207869 LoadTimingInfo load_timing_info;
7870 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7871 TestLoadTimingNotReusedWithPac(load_timing_info,
7872 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
7873
[email protected]e0c27be2009-07-15 13:09:357874 std::string response_text;
7875 rv = ReadTransaction(trans.get(), &response_text);
7876 EXPECT_EQ(OK, rv);
7877 EXPECT_EQ("Payload", response_text);
7878}
7879
[email protected]23e482282013-06-14 16:08:027880TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:277881 HttpRequestInfo request;
7882 request.method = "GET";
bncce36dca22015-04-21 22:11:237883 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:277884 request.load_flags = 0;
7885
[email protected]bb88e1d32013-05-03 23:11:077886 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:207887 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
vishal.b62985ca92015-04-17 08:45:517888 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077889 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:357890
[email protected]3fe8d2f82013-10-17 08:56:077891 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e0c27be2009-07-15 13:09:357892 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417893 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:357894
[email protected]e0c27be2009-07-15 13:09:357895 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
7896 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:377897 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:237898 0x05, // Version
7899 0x01, // Command (CONNECT)
7900 0x00, // Reserved.
7901 0x03, // Address type (DOMAINNAME).
7902 0x0F, // Length of domain (15)
7903 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
7904 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:377905 };
7906
[email protected]e0c27be2009-07-15 13:09:357907 const char kSOCKS5OkResponse[] =
7908 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
7909
7910 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237911 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
7912 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
7913 arraysize(kSOCKS5OkRequest)),
7914 MockWrite(
7915 "GET / HTTP/1.1\r\n"
7916 "Host: www.example.org\r\n"
7917 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:357918
7919 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:017920 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
7921 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:027922 MockRead("HTTP/1.0 200 OK\r\n"),
7923 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
7924 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:067925 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:027926 };
7927
[email protected]31a2bfe2010-02-09 08:03:397928 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7929 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:077930 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:027931
[email protected]8ddf8322012-02-23 18:08:067932 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077933 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:027934
[email protected]49639fa2011-12-20 23:22:417935 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:027936
[email protected]49639fa2011-12-20 23:22:417937 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:027938 EXPECT_EQ(ERR_IO_PENDING, rv);
7939
7940 rv = callback.WaitForResult();
7941 EXPECT_EQ(OK, rv);
7942
7943 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:507944 ASSERT_TRUE(response != NULL);
[email protected]3cd17242009-06-23 02:59:027945
[email protected]029c83b62013-01-24 05:28:207946 LoadTimingInfo load_timing_info;
7947 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7948 TestLoadTimingNotReusedWithPac(load_timing_info,
7949 CONNECT_TIMING_HAS_SSL_TIMES);
7950
[email protected]3cd17242009-06-23 02:59:027951 std::string response_text;
7952 rv = ReadTransaction(trans.get(), &response_text);
7953 EXPECT_EQ(OK, rv);
7954 EXPECT_EQ("Payload", response_text);
7955}
7956
[email protected]448d4ca52012-03-04 04:12:237957namespace {
7958
[email protected]04e5be32009-06-26 20:00:317959// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:067960
7961struct GroupNameTest {
7962 std::string proxy_server;
7963 std::string url;
7964 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:187965 bool ssl;
[email protected]2d731a32010-04-29 01:04:067966};
7967
7968scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:437969 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:077970 SpdySessionDependencies* session_deps_) {
7971 scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:067972
[email protected]30d4c022013-07-18 22:58:167973 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:537974 session->http_server_properties();
bnccacc0992015-03-20 20:22:227975 AlternativeService alternative_service(
bnc4988e432015-03-31 03:06:257976 AlternateProtocolFromNextProto(next_proto), "", 443);
bnc7dc7e1b42015-07-28 14:43:127977 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:227978 http_server_properties->SetAlternativeService(
bnc7dc7e1b42015-07-28 14:43:127979 HostPortPair("host.with.alternate", 80), alternative_service, 1.0,
7980 expiration);
[email protected]2d731a32010-04-29 01:04:067981
7982 return session;
7983}
7984
7985int GroupNameTransactionHelper(
7986 const std::string& url,
7987 const scoped_refptr<HttpNetworkSession>& session) {
[email protected]2d731a32010-04-29 01:04:067988 HttpRequestInfo request;
7989 request.method = "GET";
7990 request.url = GURL(url);
7991 request.load_flags = 0;
7992
[email protected]262eec82013-03-19 21:01:367993 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507994 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277995
[email protected]49639fa2011-12-20 23:22:417996 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:067997
7998 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:417999 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:068000}
8001
[email protected]448d4ca52012-03-04 04:12:238002} // namespace
8003
[email protected]23e482282013-06-14 16:08:028004TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:068005 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238006 {
8007 "", // unused
8008 "http://www.example.org/direct",
8009 "www.example.org:80",
8010 false,
8011 },
8012 {
8013 "", // unused
8014 "http://[2001:1418:13:1::25]/direct",
8015 "[2001:1418:13:1::25]:80",
8016 false,
8017 },
[email protected]04e5be32009-06-26 20:00:318018
bncce36dca22015-04-21 22:11:238019 // SSL Tests
8020 {
8021 "", // unused
8022 "https://www.example.org/direct_ssl",
8023 "ssl/www.example.org:443",
8024 true,
8025 },
8026 {
8027 "", // unused
8028 "https://[2001:1418:13:1::25]/direct",
8029 "ssl/[2001:1418:13:1::25]:443",
8030 true,
8031 },
8032 {
8033 "", // unused
8034 "http://host.with.alternate/direct",
8035 "ssl/host.with.alternate:443",
8036 true,
8037 },
[email protected]2d731a32010-04-29 01:04:068038 };
[email protected]2ff8b312010-04-26 22:20:548039
bnc55ff9da2015-08-19 18:42:358040 session_deps_.use_alternative_services = true;
[email protected]2d731a32010-04-29 01:04:068041
viettrungluue4a8b882014-10-16 06:17:388042 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078043 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028044 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:068045 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438046 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068047
8048 HttpNetworkSessionPeer peer(session);
[email protected]ab739042011-04-07 15:22:288049 CaptureGroupNameTransportSocketPool* transport_conn_pool =
8050 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138051 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348052 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]831e4a32013-11-14 02:14:448053 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8054 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028055 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
8056 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518057 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068058
8059 EXPECT_EQ(ERR_IO_PENDING,
8060 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188061 if (tests[i].ssl)
8062 EXPECT_EQ(tests[i].expected_group_name,
8063 ssl_conn_pool->last_group_name_received());
8064 else
8065 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:288066 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068067 }
[email protected]2d731a32010-04-29 01:04:068068}
8069
[email protected]23e482282013-06-14 16:08:028070TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:068071 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238072 {
8073 "http_proxy",
8074 "http://www.example.org/http_proxy_normal",
8075 "www.example.org:80",
8076 false,
8077 },
[email protected]2d731a32010-04-29 01:04:068078
bncce36dca22015-04-21 22:11:238079 // SSL Tests
8080 {
8081 "http_proxy",
8082 "https://www.example.org/http_connect_ssl",
8083 "ssl/www.example.org:443",
8084 true,
8085 },
[email protected]af3490e2010-10-16 21:02:298086
bncce36dca22015-04-21 22:11:238087 {
8088 "http_proxy",
8089 "http://host.with.alternate/direct",
8090 "ssl/host.with.alternate:443",
8091 true,
8092 },
[email protected]45499252013-01-23 17:12:568093
bncce36dca22015-04-21 22:11:238094 {
8095 "http_proxy",
8096 "ftp://ftp.google.com/http_proxy_normal",
8097 "ftp/ftp.google.com:21",
8098 false,
8099 },
[email protected]2d731a32010-04-29 01:04:068100 };
8101
bnc55ff9da2015-08-19 18:42:358102 session_deps_.use_alternative_services = true;
[email protected]2d731a32010-04-29 01:04:068103
viettrungluue4a8b882014-10-16 06:17:388104 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078105 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028106 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:068107 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438108 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:068109
8110 HttpNetworkSessionPeer peer(session);
8111
[email protected]e60e47a2010-07-14 03:37:188112 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:138113 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:348114 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138115 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348116 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028117
[email protected]831e4a32013-11-14 02:14:448118 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8119 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028120 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
8121 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518122 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]2d731a32010-04-29 01:04:068123
8124 EXPECT_EQ(ERR_IO_PENDING,
8125 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188126 if (tests[i].ssl)
8127 EXPECT_EQ(tests[i].expected_group_name,
8128 ssl_conn_pool->last_group_name_received());
8129 else
8130 EXPECT_EQ(tests[i].expected_group_name,
8131 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:068132 }
[email protected]2d731a32010-04-29 01:04:068133}
8134
[email protected]23e482282013-06-14 16:08:028135TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:068136 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:238137 {
8138 "socks4://socks_proxy:1080",
8139 "http://www.example.org/socks4_direct",
8140 "socks4/www.example.org:80",
8141 false,
8142 },
8143 {
8144 "socks5://socks_proxy:1080",
8145 "http://www.example.org/socks5_direct",
8146 "socks5/www.example.org:80",
8147 false,
8148 },
[email protected]2d731a32010-04-29 01:04:068149
bncce36dca22015-04-21 22:11:238150 // SSL Tests
8151 {
8152 "socks4://socks_proxy:1080",
8153 "https://www.example.org/socks4_ssl",
8154 "socks4/ssl/www.example.org:443",
8155 true,
8156 },
8157 {
8158 "socks5://socks_proxy:1080",
8159 "https://www.example.org/socks5_ssl",
8160 "socks5/ssl/www.example.org:443",
8161 true,
8162 },
[email protected]af3490e2010-10-16 21:02:298163
bncce36dca22015-04-21 22:11:238164 {
8165 "socks4://socks_proxy:1080",
8166 "http://host.with.alternate/direct",
8167 "socks4/ssl/host.with.alternate:443",
8168 true,
8169 },
[email protected]04e5be32009-06-26 20:00:318170 };
8171
bnc55ff9da2015-08-19 18:42:358172 session_deps_.use_alternative_services = true;
[email protected]2ff8b312010-04-26 22:20:548173
viettrungluue4a8b882014-10-16 06:17:388174 for (size_t i = 0; i < arraysize(tests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:078175 session_deps_.proxy_service.reset(
[email protected]8b114dd72011-03-25 05:33:028176 ProxyService::CreateFixed(tests[i].proxy_server));
[email protected]2d731a32010-04-29 01:04:068177 scoped_refptr<HttpNetworkSession> session(
[email protected]8a0fc822013-06-27 20:52:438178 SetupSessionForGroupNameTests(GetParam(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:028179
[email protected]2d731a32010-04-29 01:04:068180 HttpNetworkSessionPeer peer(session);
[email protected]04e5be32009-06-26 20:00:318181
[email protected]e60e47a2010-07-14 03:37:188182 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:138183 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348184 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:138185 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:348186 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:028187
[email protected]831e4a32013-11-14 02:14:448188 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
8189 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:028190 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
8191 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchenge3d1ddc2014-10-15 19:30:518192 peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]04e5be32009-06-26 20:00:318193
[email protected]262eec82013-03-19 21:01:368194 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508195 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:318196
[email protected]2d731a32010-04-29 01:04:068197 EXPECT_EQ(ERR_IO_PENDING,
8198 GroupNameTransactionHelper(tests[i].url, session));
[email protected]e60e47a2010-07-14 03:37:188199 if (tests[i].ssl)
8200 EXPECT_EQ(tests[i].expected_group_name,
8201 ssl_conn_pool->last_group_name_received());
8202 else
8203 EXPECT_EQ(tests[i].expected_group_name,
8204 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:318205 }
8206}
8207
[email protected]23e482282013-06-14 16:08:028208TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:278209 HttpRequestInfo request;
8210 request.method = "GET";
bncce36dca22015-04-21 22:11:238211 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278212
[email protected]bb88e1d32013-05-03 23:11:078213 session_deps_.proxy_service.reset(
[email protected]81cdfcd2010-10-16 00:49:008214 ProxyService::CreateFixed("myproxy:70;foobar:80"));
[email protected]b59ff372009-07-15 22:04:328215
[email protected]69719062010-01-05 20:09:218216 // This simulates failure resolving all hostnames; that means we will fail
8217 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:078218 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:328219
[email protected]3fe8d2f82013-10-17 08:56:078220 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]9172a982009-06-06 00:30:258221 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418222 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:258223
[email protected]49639fa2011-12-20 23:22:418224 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:258225
[email protected]49639fa2011-12-20 23:22:418226 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:258227 EXPECT_EQ(ERR_IO_PENDING, rv);
8228
[email protected]9172a982009-06-06 00:30:258229 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:018230 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:258231}
8232
[email protected]685af592010-05-11 19:31:248233// Base test to make sure that when the load flags for a request specify to
8234// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:028235void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:078236 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:278237 // Issue a request, asking to bypass the cache(s).
8238 HttpRequestInfo request;
8239 request.method = "GET";
8240 request.load_flags = load_flags;
bncce36dca22015-04-21 22:11:238241 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278242
[email protected]a2c2fb92009-07-18 07:31:048243 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:078244 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:328245
[email protected]3fe8d2f82013-10-17 08:56:078246 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8247 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418248 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:288249
bncce36dca22015-04-21 22:11:238250 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288251 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:298252 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:078253 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238254 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8255 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:478256 EXPECT_EQ(ERR_IO_PENDING, rv);
8257 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288258 EXPECT_EQ(OK, rv);
8259
8260 // Verify that it was added to host cache, by doing a subsequent async lookup
8261 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:078262 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:238263 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
8264 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:328265 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:288266
bncce36dca22015-04-21 22:11:238267 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:288268 // we can tell if the next lookup hit the cache, or the "network".
8269 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:238270 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:288271
8272 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
8273 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:068274 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:398275 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078276 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:288277
[email protected]3b9cca42009-06-16 01:08:288278 // Run the request.
[email protected]49639fa2011-12-20 23:22:418279 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:288280 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:418281 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:288282
8283 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:238284 // "www.example.org".
[email protected]3b9cca42009-06-16 01:08:288285 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
8286}
8287
[email protected]685af592010-05-11 19:31:248288// There are multiple load flags that should trigger the host cache bypass.
8289// Test each in isolation:
[email protected]23e482282013-06-14 16:08:028290TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:248291 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
8292}
8293
[email protected]23e482282013-06-14 16:08:028294TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:248295 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
8296}
8297
[email protected]23e482282013-06-14 16:08:028298TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:248299 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
8300}
8301
[email protected]0877e3d2009-10-17 22:29:578302// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:028303TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:578304 HttpRequestInfo request;
8305 request.method = "GET";
8306 request.url = GURL("http://www.foo.com/");
8307 request.load_flags = 0;
8308
8309 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:068310 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578311 };
[email protected]31a2bfe2010-02-09 08:03:398312 StaticSocketDataProvider data(NULL, 0,
8313 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:078314 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078315 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578316
[email protected]49639fa2011-12-20 23:22:418317 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578318
8319 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418320 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578321
[email protected]49639fa2011-12-20 23:22:418322 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578323 EXPECT_EQ(ERR_IO_PENDING, rv);
8324
8325 rv = callback.WaitForResult();
8326 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
8327}
8328
zmo9528c9f42015-08-04 22:12:088329// Check that a connection closed after the start of the headers finishes ok.
8330TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:578331 HttpRequestInfo request;
8332 request.method = "GET";
8333 request.url = GURL("http://www.foo.com/");
8334 request.load_flags = 0;
8335
8336 MockRead data_reads[] = {
8337 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:068338 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578339 };
8340
[email protected]31a2bfe2010-02-09 08:03:398341 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078342 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3fe8d2f82013-10-17 08:56:078343 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578344
[email protected]49639fa2011-12-20 23:22:418345 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578346
8347 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418348 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578349
[email protected]49639fa2011-12-20 23:22:418350 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578351 EXPECT_EQ(ERR_IO_PENDING, rv);
8352
8353 rv = callback.WaitForResult();
zmo9528c9f42015-08-04 22:12:088354 EXPECT_EQ(OK, rv);
8355
8356 const HttpResponseInfo* response = trans->GetResponseInfo();
8357 ASSERT_TRUE(response != NULL);
8358
8359 EXPECT_TRUE(response->headers.get() != NULL);
8360 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8361
8362 std::string response_data;
8363 rv = ReadTransaction(trans.get(), &response_data);
8364 EXPECT_EQ(OK, rv);
8365 EXPECT_EQ("", response_data);
[email protected]0877e3d2009-10-17 22:29:578366}
8367
8368// Make sure that a dropped connection while draining the body for auth
8369// restart does the right thing.
[email protected]23e482282013-06-14 16:08:028370TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:578371 HttpRequestInfo request;
8372 request.method = "GET";
bncce36dca22015-04-21 22:11:238373 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578374 request.load_flags = 0;
8375
8376 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238377 MockWrite(
8378 "GET / HTTP/1.1\r\n"
8379 "Host: www.example.org\r\n"
8380 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578381 };
8382
8383 MockRead data_reads1[] = {
8384 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
8385 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8386 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8387 MockRead("Content-Length: 14\r\n\r\n"),
8388 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:068389 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:578390 };
8391
[email protected]31a2bfe2010-02-09 08:03:398392 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8393 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:078394 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:578395
8396 // After calling trans->RestartWithAuth(), this is the request we should
8397 // be issuing -- the final header line contains the credentials.
8398 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238399 MockWrite(
8400 "GET / HTTP/1.1\r\n"
8401 "Host: www.example.org\r\n"
8402 "Connection: keep-alive\r\n"
8403 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:578404 };
8405
8406 // Lastly, the server responds with the actual content.
8407 MockRead data_reads2[] = {
8408 MockRead("HTTP/1.1 200 OK\r\n"),
8409 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8410 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068411 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:578412 };
8413
[email protected]31a2bfe2010-02-09 08:03:398414 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8415 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:078416 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3fe8d2f82013-10-17 08:56:078417 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578418
[email protected]49639fa2011-12-20 23:22:418419 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:578420
[email protected]262eec82013-03-19 21:01:368421 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508422 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508423
[email protected]49639fa2011-12-20 23:22:418424 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578425 EXPECT_EQ(ERR_IO_PENDING, rv);
8426
8427 rv = callback1.WaitForResult();
8428 EXPECT_EQ(OK, rv);
8429
8430 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508431 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048432 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:578433
[email protected]49639fa2011-12-20 23:22:418434 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:578435
[email protected]49639fa2011-12-20 23:22:418436 rv = trans->RestartWithAuth(
8437 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:578438 EXPECT_EQ(ERR_IO_PENDING, rv);
8439
8440 rv = callback2.WaitForResult();
8441 EXPECT_EQ(OK, rv);
8442
8443 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508444 ASSERT_TRUE(response != NULL);
[email protected]0877e3d2009-10-17 22:29:578445 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8446 EXPECT_EQ(100, response->headers->GetContentLength());
8447}
8448
8449// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:028450TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
[email protected]bb88e1d32013-05-03 23:11:078451 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
[email protected]0877e3d2009-10-17 22:29:578452
8453 HttpRequestInfo request;
8454 request.method = "GET";
bncce36dca22015-04-21 22:11:238455 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:578456 request.load_flags = 0;
8457
8458 MockRead proxy_reads[] = {
8459 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:068460 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:578461 };
8462
[email protected]31a2bfe2010-02-09 08:03:398463 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:068464 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:578465
[email protected]bb88e1d32013-05-03 23:11:078466 session_deps_.socket_factory->AddSocketDataProvider(&data);
8467 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:578468
[email protected]49639fa2011-12-20 23:22:418469 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:578470
[email protected]bb88e1d32013-05-03 23:11:078471 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:578472
[email protected]3fe8d2f82013-10-17 08:56:078473 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:578474 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418475 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:578476
[email protected]49639fa2011-12-20 23:22:418477 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:578478 EXPECT_EQ(ERR_IO_PENDING, rv);
8479
8480 rv = callback.WaitForResult();
8481 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
8482}
8483
[email protected]23e482282013-06-14 16:08:028484TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:468485 HttpRequestInfo request;
8486 request.method = "GET";
bncce36dca22015-04-21 22:11:238487 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:468488 request.load_flags = 0;
8489
[email protected]3fe8d2f82013-10-17 08:56:078490 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278491 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418492 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278493
[email protected]e22e1362009-11-23 21:31:128494 MockRead data_reads[] = {
8495 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068496 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:128497 };
[email protected]9492e4a2010-02-24 00:58:468498
8499 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078500 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:468501
[email protected]49639fa2011-12-20 23:22:418502 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:468503
[email protected]49639fa2011-12-20 23:22:418504 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:468505 EXPECT_EQ(ERR_IO_PENDING, rv);
8506
8507 EXPECT_EQ(OK, callback.WaitForResult());
8508
8509 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508510 ASSERT_TRUE(response != NULL);
[email protected]9492e4a2010-02-24 00:58:468511
[email protected]90499482013-06-01 00:39:508512 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]9492e4a2010-02-24 00:58:468513 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8514
8515 std::string response_data;
8516 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:238517 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:128518}
8519
[email protected]23e482282013-06-14 16:08:028520TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:158521 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:528522 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
[email protected]95d88ffe2010-02-04 21:25:338523 const uint64 kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:218524 UploadFileElementReader::ScopedOverridingContentLengthForTests
8525 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:338526
[email protected]b2d26cfd2012-12-11 10:36:068527 ScopedVector<UploadElementReader> element_readers;
8528 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:458529 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
8530 temp_file_path, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:078531 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278532
8533 HttpRequestInfo request;
8534 request.method = "POST";
bncce36dca22015-04-21 22:11:238535 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278536 request.upload_data_stream = &upload_data_stream;
8537 request.load_flags = 0;
8538
[email protected]3fe8d2f82013-10-17 08:56:078539 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278540 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418541 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:338542
8543 MockRead data_reads[] = {
8544 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
8545 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068546 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:338547 };
[email protected]31a2bfe2010-02-09 08:03:398548 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078549 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:338550
[email protected]49639fa2011-12-20 23:22:418551 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:338552
[email protected]49639fa2011-12-20 23:22:418553 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:338554 EXPECT_EQ(ERR_IO_PENDING, rv);
8555
8556 rv = callback.WaitForResult();
8557 EXPECT_EQ(OK, rv);
8558
8559 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508560 ASSERT_TRUE(response != NULL);
[email protected]95d88ffe2010-02-04 21:25:338561
[email protected]90499482013-06-01 00:39:508562 EXPECT_TRUE(response->headers.get() != NULL);
[email protected]95d88ffe2010-02-04 21:25:338563 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
8564
8565 std::string response_data;
8566 rv = ReadTransaction(trans.get(), &response_data);
8567 EXPECT_EQ(OK, rv);
8568 EXPECT_EQ("hello world", response_data);
8569
[email protected]dd3aa792013-07-16 19:10:238570 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:338571}
8572
[email protected]23e482282013-06-14 16:08:028573TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:158574 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:528575 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:368576 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:308577 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:368578 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:118579 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:368580
[email protected]b2d26cfd2012-12-11 10:36:068581 ScopedVector<UploadElementReader> element_readers;
8582 element_readers.push_back(
skyostil4891b25b2015-06-11 11:43:458583 new UploadFileElementReader(base::ThreadTaskRunnerHandle::Get().get(),
8584 temp_file, 0, kuint64max, base::Time()));
mmenkecbc2b712014-10-09 20:29:078585 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]329b68b2012-11-14 17:54:278586
8587 HttpRequestInfo request;
8588 request.method = "POST";
bncce36dca22015-04-21 22:11:238589 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:278590 request.upload_data_stream = &upload_data_stream;
8591 request.load_flags = 0;
8592
[email protected]999dd8c2013-11-12 06:45:548593 // If we try to upload an unreadable file, the transaction should fail.
[email protected]3fe8d2f82013-10-17 08:56:078594 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]329b68b2012-11-14 17:54:278595 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418596 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:368597
[email protected]999dd8c2013-11-12 06:45:548598 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:078599 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:368600
[email protected]49639fa2011-12-20 23:22:418601 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:368602
[email protected]49639fa2011-12-20 23:22:418603 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:368604 EXPECT_EQ(ERR_IO_PENDING, rv);
8605
8606 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:548607 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:368608
[email protected]dd3aa792013-07-16 19:10:238609 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:368610}
8611
[email protected]02cad5d2013-10-02 08:14:038612TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
8613 class FakeUploadElementReader : public UploadElementReader {
8614 public:
8615 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:208616 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:038617
8618 const CompletionCallback& callback() const { return callback_; }
8619
8620 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:208621 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038622 callback_ = callback;
8623 return ERR_IO_PENDING;
8624 }
dchengb03027d2014-10-21 12:00:208625 uint64 GetContentLength() const override { return 0; }
8626 uint64 BytesRemaining() const override { return 0; }
8627 int Read(IOBuffer* buf,
8628 int buf_length,
8629 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:038630 return ERR_FAILED;
8631 }
8632
8633 private:
8634 CompletionCallback callback_;
8635 };
8636
8637 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
8638 ScopedVector<UploadElementReader> element_readers;
8639 element_readers.push_back(fake_reader);
mmenkecbc2b712014-10-09 20:29:078640 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02cad5d2013-10-02 08:14:038641
8642 HttpRequestInfo request;
8643 request.method = "POST";
bncce36dca22015-04-21 22:11:238644 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:038645 request.upload_data_stream = &upload_data_stream;
8646 request.load_flags = 0;
8647
[email protected]3fe8d2f82013-10-17 08:56:078648 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02cad5d2013-10-02 08:14:038649 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418650 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:038651
8652 StaticSocketDataProvider data;
8653 session_deps_.socket_factory->AddSocketDataProvider(&data);
8654
8655 TestCompletionCallback callback;
8656 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8657 EXPECT_EQ(ERR_IO_PENDING, rv);
8658 base::MessageLoop::current()->RunUntilIdle();
8659
8660 // Transaction is pending on request body initialization.
8661 ASSERT_FALSE(fake_reader->callback().is_null());
8662
8663 // Return Init()'s result after the transaction gets destroyed.
8664 trans.reset();
8665 fake_reader->callback().Run(OK); // Should not crash.
8666}
8667
[email protected]aeefc9e82010-02-19 16:18:278668// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:028669TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:278670 HttpRequestInfo request;
8671 request.method = "GET";
bncce36dca22015-04-21 22:11:238672 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:278673 request.load_flags = 0;
8674
8675 // First transaction will request a resource and receive a Basic challenge
8676 // with realm="first_realm".
8677 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238678 MockWrite(
8679 "GET / HTTP/1.1\r\n"
8680 "Host: www.example.org\r\n"
8681 "Connection: keep-alive\r\n"
8682 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278683 };
8684 MockRead data_reads1[] = {
8685 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8686 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8687 "\r\n"),
8688 };
8689
8690 // After calling trans->RestartWithAuth(), provide an Authentication header
8691 // for first_realm. The server will reject and provide a challenge with
8692 // second_realm.
8693 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238694 MockWrite(
8695 "GET / HTTP/1.1\r\n"
8696 "Host: www.example.org\r\n"
8697 "Connection: keep-alive\r\n"
8698 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
8699 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278700 };
8701 MockRead data_reads2[] = {
8702 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8703 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
8704 "\r\n"),
8705 };
8706
8707 // This again fails, and goes back to first_realm. Make sure that the
8708 // entry is removed from cache.
8709 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238710 MockWrite(
8711 "GET / HTTP/1.1\r\n"
8712 "Host: www.example.org\r\n"
8713 "Connection: keep-alive\r\n"
8714 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
8715 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278716 };
8717 MockRead data_reads3[] = {
8718 MockRead("HTTP/1.1 401 Unauthorized\r\n"
8719 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
8720 "\r\n"),
8721 };
8722
8723 // Try one last time (with the correct password) and get the resource.
8724 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:238725 MockWrite(
8726 "GET / HTTP/1.1\r\n"
8727 "Host: www.example.org\r\n"
8728 "Connection: keep-alive\r\n"
8729 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
8730 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:278731 };
8732 MockRead data_reads4[] = {
8733 MockRead("HTTP/1.1 200 OK\r\n"
8734 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:508735 "Content-Length: 5\r\n"
8736 "\r\n"
8737 "hello"),
[email protected]aeefc9e82010-02-19 16:18:278738 };
8739
8740 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
8741 data_writes1, arraysize(data_writes1));
8742 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
8743 data_writes2, arraysize(data_writes2));
8744 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
8745 data_writes3, arraysize(data_writes3));
8746 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
8747 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:078748 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8749 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8750 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8751 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:278752
[email protected]49639fa2011-12-20 23:22:418753 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:278754
[email protected]3fe8d2f82013-10-17 08:56:078755 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0b0bf032010-09-21 18:08:508756 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418757 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:508758
[email protected]aeefc9e82010-02-19 16:18:278759 // Issue the first request with Authorize headers. There should be a
8760 // password prompt for first_realm waiting to be filled in after the
8761 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418762 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:278763 EXPECT_EQ(ERR_IO_PENDING, rv);
8764 rv = callback1.WaitForResult();
8765 EXPECT_EQ(OK, rv);
8766 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508767 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048768 const AuthChallengeInfo* challenge = response->auth_challenge.get();
8769 ASSERT_FALSE(challenge == NULL);
8770 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238771 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048772 EXPECT_EQ("first_realm", challenge->realm);
8773 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278774
8775 // Issue the second request with an incorrect password. There should be a
8776 // password prompt for second_realm waiting to be filled in after the
8777 // transaction completes.
[email protected]49639fa2011-12-20 23:22:418778 TestCompletionCallback callback2;
8779 rv = trans->RestartWithAuth(
8780 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:278781 EXPECT_EQ(ERR_IO_PENDING, rv);
8782 rv = callback2.WaitForResult();
8783 EXPECT_EQ(OK, rv);
8784 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508785 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048786 challenge = response->auth_challenge.get();
8787 ASSERT_FALSE(challenge == NULL);
8788 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238789 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048790 EXPECT_EQ("second_realm", challenge->realm);
8791 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278792
8793 // Issue the third request with another incorrect password. There should be
8794 // a password prompt for first_realm waiting to be filled in. If the password
8795 // prompt is not present, it indicates that the HttpAuthCacheEntry for
8796 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:418797 TestCompletionCallback callback3;
8798 rv = trans->RestartWithAuth(
8799 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:278800 EXPECT_EQ(ERR_IO_PENDING, rv);
8801 rv = callback3.WaitForResult();
8802 EXPECT_EQ(OK, rv);
8803 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508804 ASSERT_TRUE(response != NULL);
[email protected]79cb5c12011-09-12 13:12:048805 challenge = response->auth_challenge.get();
8806 ASSERT_FALSE(challenge == NULL);
8807 EXPECT_FALSE(challenge->is_proxy);
bncce36dca22015-04-21 22:11:238808 EXPECT_EQ("www.example.org:80", challenge->challenger.ToString());
[email protected]79cb5c12011-09-12 13:12:048809 EXPECT_EQ("first_realm", challenge->realm);
8810 EXPECT_EQ("basic", challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:278811
8812 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:418813 TestCompletionCallback callback4;
8814 rv = trans->RestartWithAuth(
8815 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:278816 EXPECT_EQ(ERR_IO_PENDING, rv);
8817 rv = callback4.WaitForResult();
8818 EXPECT_EQ(OK, rv);
8819 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:508820 ASSERT_TRUE(response != NULL);
[email protected]aeefc9e82010-02-19 16:18:278821 EXPECT_TRUE(response->auth_challenge.get() == NULL);
8822}
8823
bncc958faa2015-07-31 18:14:528824TEST_P(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
8825 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:358826 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:528827
8828 std::string alternative_service_http_header =
8829 GetAlternativeServiceHttpHeader();
8830
8831 MockRead data_reads[] = {
8832 MockRead("HTTP/1.1 200 OK\r\n"),
8833 MockRead(alternative_service_http_header.c_str()),
8834 MockRead("\r\n"),
8835 MockRead("hello world"),
8836 MockRead(SYNCHRONOUS, OK),
8837 };
8838
8839 HttpRequestInfo request;
8840 request.method = "GET";
8841 request.url = GURL("http://www.example.org/");
8842 request.load_flags = 0;
8843
8844 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8845
8846 session_deps_.socket_factory->AddSocketDataProvider(&data);
8847
8848 TestCompletionCallback callback;
8849
8850 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8851 scoped_ptr<HttpTransaction> trans(
8852 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8853
8854 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8855 EXPECT_EQ(ERR_IO_PENDING, rv);
8856
8857 HostPortPair http_host_port_pair("www.example.org", 80);
8858 HttpServerProperties& http_server_properties =
8859 *session->http_server_properties();
8860 AlternativeServiceVector alternative_service_vector =
8861 http_server_properties.GetAlternativeServices(http_host_port_pair);
8862 EXPECT_TRUE(alternative_service_vector.empty());
8863
8864 EXPECT_EQ(OK, callback.WaitForResult());
8865
8866 const HttpResponseInfo* response = trans->GetResponseInfo();
8867 ASSERT_TRUE(response != NULL);
8868 ASSERT_TRUE(response->headers.get() != NULL);
8869 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8870 EXPECT_FALSE(response->was_fetched_via_spdy);
8871 EXPECT_FALSE(response->was_npn_negotiated);
8872
8873 std::string response_data;
8874 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8875 EXPECT_EQ("hello world", response_data);
8876
8877 alternative_service_vector =
8878 http_server_properties.GetAlternativeServices(http_host_port_pair);
8879 ASSERT_EQ(1u, alternative_service_vector.size());
8880 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
8881 alternative_service_vector[0].protocol);
8882 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
8883 EXPECT_EQ(443, alternative_service_vector[0].port);
8884}
8885
bnc54ec34b72015-08-26 19:34:568886// Alternative Service headers must be ignored when |use_alternative_services|
8887// is false.
8888TEST_P(HttpNetworkTransactionTest, DoNotHonorAlternativeServiceHeader) {
8889 session_deps_.next_protos = SpdyNextProtos();
8890 session_deps_.use_alternative_services = false;
8891
8892 std::string alternative_service_http_header =
8893 GetAlternativeServiceHttpHeader();
8894
8895 MockRead data_reads[] = {
8896 MockRead("HTTP/1.1 200 OK\r\n"),
8897 MockRead(alternative_service_http_header.c_str()),
8898 MockRead("\r\n"),
8899 MockRead("hello world"),
8900 MockRead(SYNCHRONOUS, OK),
8901 };
8902
8903 HttpRequestInfo request;
8904 request.method = "GET";
8905 request.url = GURL("http://www.example.org/");
8906 request.load_flags = 0;
8907
8908 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
8909
8910 session_deps_.socket_factory->AddSocketDataProvider(&data);
8911
8912 TestCompletionCallback callback;
8913
8914 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8915 scoped_ptr<HttpTransaction> trans(
8916 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8917
8918 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8919 EXPECT_EQ(ERR_IO_PENDING, rv);
8920
8921 HostPortPair http_host_port_pair("www.example.org", 80);
8922 HttpServerProperties& http_server_properties =
8923 *session->http_server_properties();
8924 AlternativeServiceVector alternative_service_vector =
8925 http_server_properties.GetAlternativeServices(http_host_port_pair);
8926 EXPECT_TRUE(alternative_service_vector.empty());
8927
8928 EXPECT_EQ(OK, callback.WaitForResult());
8929
8930 const HttpResponseInfo* response = trans->GetResponseInfo();
8931 ASSERT_TRUE(response != nullptr);
8932 ASSERT_TRUE(response->headers.get() != nullptr);
8933 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8934 EXPECT_FALSE(response->was_fetched_via_spdy);
8935 EXPECT_FALSE(response->was_npn_negotiated);
8936
8937 std::string response_data;
8938 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8939 EXPECT_EQ("hello world", response_data);
8940
8941 alternative_service_vector =
8942 http_server_properties.GetAlternativeServices(http_host_port_pair);
8943 EXPECT_TRUE(alternative_service_vector.empty());
8944}
8945
bncc958faa2015-07-31 18:14:528946TEST_P(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeader) {
8947 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:358948 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:528949
8950 MockRead data_reads[] = {
8951 MockRead("HTTP/1.1 200 OK\r\n"),
8952 MockRead("Alt-Svc: "),
8953 MockRead(GetAlternateProtocolFromParam()),
8954 MockRead("=\"www.example.com:443\";p=1.0,"),
8955 MockRead("quic=\":1234\"\r\n\r\n"),
8956 MockRead("hello world"),
8957 MockRead(SYNCHRONOUS, OK),
8958 };
8959
8960 HttpRequestInfo request;
8961 request.method = "GET";
8962 request.url = GURL("http://www.example.org/");
8963 request.load_flags = 0;
8964
8965 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
8966
8967 session_deps_.socket_factory->AddSocketDataProvider(&data);
8968
8969 TestCompletionCallback callback;
8970
8971 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8972 scoped_ptr<HttpTransaction> trans(
8973 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8974
8975 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8976 EXPECT_EQ(ERR_IO_PENDING, rv);
8977
8978 HostPortPair http_host_port_pair("www.example.org", 80);
8979 HttpServerProperties& http_server_properties =
8980 *session->http_server_properties();
8981 AlternativeServiceVector alternative_service_vector =
8982 http_server_properties.GetAlternativeServices(http_host_port_pair);
8983 EXPECT_TRUE(alternative_service_vector.empty());
8984
8985 EXPECT_EQ(OK, callback.WaitForResult());
8986
8987 const HttpResponseInfo* response = trans->GetResponseInfo();
8988 ASSERT_TRUE(response != NULL);
8989 ASSERT_TRUE(response->headers.get() != NULL);
8990 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8991 EXPECT_FALSE(response->was_fetched_via_spdy);
8992 EXPECT_FALSE(response->was_npn_negotiated);
8993
8994 std::string response_data;
8995 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
8996 EXPECT_EQ("hello world", response_data);
8997
8998 alternative_service_vector =
8999 http_server_properties.GetAlternativeServices(http_host_port_pair);
9000 ASSERT_EQ(2u, alternative_service_vector.size());
9001 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
9002 alternative_service_vector[0].protocol);
9003 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9004 EXPECT_EQ(443, alternative_service_vector[0].port);
9005 EXPECT_EQ(QUIC, alternative_service_vector[1].protocol);
9006 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
9007 EXPECT_EQ(1234, alternative_service_vector[1].port);
9008}
9009
bnc54ec34b72015-08-26 19:34:569010// Alternate Protocol headers must be honored even if |use_alternative_services|
9011// is false.
[email protected]23e482282013-06-14 16:08:029012TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
[email protected]d7599122014-05-24 03:37:239013 session_deps_.next_protos = SpdyNextProtos();
bnc54ec34b72015-08-26 19:34:569014 session_deps_.use_alternative_services = false;
[email protected]a2cb8122010-03-10 17:22:429015
[email protected]8a0fc822013-06-27 20:52:439016 std::string alternate_protocol_http_header =
9017 GetAlternateProtocolHttpHeader();
9018
[email protected]564b4912010-03-09 16:30:429019 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529020 MockRead("HTTP/1.1 200 OK\r\n"),
9021 MockRead(alternate_protocol_http_header.c_str()),
9022 MockRead("\r\n"),
9023 MockRead("hello world"),
9024 MockRead(SYNCHRONOUS, OK),
[email protected]564b4912010-03-09 16:30:429025 };
9026
9027 HttpRequestInfo request;
9028 request.method = "GET";
bncce36dca22015-04-21 22:11:239029 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:429030 request.load_flags = 0;
9031
9032 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9033
[email protected]bb88e1d32013-05-03 23:11:079034 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]564b4912010-03-09 16:30:429035
[email protected]49639fa2011-12-20 23:22:419036 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:429037
[email protected]bb88e1d32013-05-03 23:11:079038 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369039 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509040 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]564b4912010-03-09 16:30:429041
[email protected]49639fa2011-12-20 23:22:419042 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:429043 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]9e743cd2010-03-16 07:03:539044
bncce36dca22015-04-21 22:11:239045 HostPortPair http_host_port_pair("www.example.org", 80);
[email protected]9801e3702014-03-07 09:33:559046 HttpServerProperties& http_server_properties =
[email protected]17291a022011-10-10 07:32:539047 *session->http_server_properties();
bncd9b132e2015-07-08 05:16:109048 AlternativeServiceVector alternative_service_vector =
9049 http_server_properties.GetAlternativeServices(http_host_port_pair);
9050 EXPECT_TRUE(alternative_service_vector.empty());
[email protected]564b4912010-03-09 16:30:429051
9052 EXPECT_EQ(OK, callback.WaitForResult());
9053
9054 const HttpResponseInfo* response = trans->GetResponseInfo();
9055 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509056 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:429057 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539058 EXPECT_FALSE(response->was_fetched_via_spdy);
9059 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]564b4912010-03-09 16:30:429060
9061 std::string response_data;
9062 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9063 EXPECT_EQ("hello world", response_data);
9064
bncd9b132e2015-07-08 05:16:109065 alternative_service_vector =
9066 http_server_properties.GetAlternativeServices(http_host_port_pair);
9067 ASSERT_EQ(1u, alternative_service_vector.size());
9068 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc181b39a2015-03-17 21:36:479069 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
bncd9b132e2015-07-08 05:16:109070 alternative_service_vector[0].protocol);
[email protected]564b4912010-03-09 16:30:429071}
9072
rch89c6e102015-03-18 18:56:529073TEST_P(HttpNetworkTransactionTest, EmptyAlternateProtocolHeader) {
9074 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359075 session_deps_.use_alternative_services = true;
rch89c6e102015-03-18 18:56:529076
9077 MockRead data_reads[] = {
9078 MockRead("HTTP/1.1 200 OK\r\n"),
9079 MockRead("Alternate-Protocol: \r\n\r\n"),
9080 MockRead("hello world"),
9081 MockRead(SYNCHRONOUS, OK),
9082 };
9083
9084 HttpRequestInfo request;
9085 request.method = "GET";
bncce36dca22015-04-21 22:11:239086 request.url = GURL("http://www.example.org/");
rch89c6e102015-03-18 18:56:529087 request.load_flags = 0;
9088
9089 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9090
9091 session_deps_.socket_factory->AddSocketDataProvider(&data);
9092
9093 TestCompletionCallback callback;
9094
9095 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9096
bncce36dca22015-04-21 22:11:239097 HostPortPair http_host_port_pair("www.example.org", 80);
rch89c6e102015-03-18 18:56:529098 HttpServerProperties& http_server_properties =
9099 *session->http_server_properties();
bnccacc0992015-03-20 20:22:229100 AlternativeService alternative_service(QUIC, "", 80);
bnc7dc7e1b42015-07-28 14:43:129101 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9102 http_server_properties.SetAlternativeService(
9103 http_host_port_pair, alternative_service, 1.0, expiration);
bnccacc0992015-03-20 20:22:229104
bncd9b132e2015-07-08 05:16:109105 AlternativeServiceVector alternative_service_vector =
9106 http_server_properties.GetAlternativeServices(http_host_port_pair);
9107 ASSERT_EQ(1u, alternative_service_vector.size());
9108 EXPECT_EQ(QUIC, alternative_service_vector[0].protocol);
rch89c6e102015-03-18 18:56:529109
9110 scoped_ptr<HttpTransaction> trans(
9111 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9112
9113 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9114 EXPECT_EQ(ERR_IO_PENDING, rv);
9115
9116 EXPECT_EQ(OK, callback.WaitForResult());
9117
9118 const HttpResponseInfo* response = trans->GetResponseInfo();
9119 ASSERT_TRUE(response != NULL);
9120 ASSERT_TRUE(response->headers.get() != NULL);
9121 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9122 EXPECT_FALSE(response->was_fetched_via_spdy);
9123 EXPECT_FALSE(response->was_npn_negotiated);
9124
9125 std::string response_data;
9126 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9127 EXPECT_EQ("hello world", response_data);
9128
bncd9b132e2015-07-08 05:16:109129 alternative_service_vector =
9130 http_server_properties.GetAlternativeServices(http_host_port_pair);
9131 EXPECT_TRUE(alternative_service_vector.empty());
rch89c6e102015-03-18 18:56:529132}
9133
bncc958faa2015-07-31 18:14:529134TEST_P(HttpNetworkTransactionTest, AltSvcOverwritesAlternateProtocol) {
9135 session_deps_.next_protos = SpdyNextProtos();
bnc55ff9da2015-08-19 18:42:359136 session_deps_.use_alternative_services = true;
bncc958faa2015-07-31 18:14:529137
9138 std::string alternative_service_http_header =
9139 GetAlternativeServiceHttpHeader();
9140 std::string alternate_protocol_http_header = GetAlternateProtocolHttpHeader();
9141
9142 MockRead data_reads[] = {
9143 MockRead("HTTP/1.1 200 OK\r\n"),
9144 MockRead(alternative_service_http_header.c_str()),
9145 MockRead(alternate_protocol_http_header.c_str()),
9146 MockRead("\r\n"),
9147 MockRead("hello world"),
9148 MockRead(SYNCHRONOUS, OK),
9149 };
9150
9151 HttpRequestInfo request;
9152 request.method = "GET";
9153 request.url = GURL("http://www.example.org/");
9154 request.load_flags = 0;
9155
9156 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9157
9158 session_deps_.socket_factory->AddSocketDataProvider(&data);
9159
9160 TestCompletionCallback callback;
9161
9162 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9163 scoped_ptr<HttpTransaction> trans(
9164 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9165
9166 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9167 EXPECT_EQ(ERR_IO_PENDING, rv);
9168
9169 HostPortPair http_host_port_pair("www.example.org", 80);
9170 HttpServerProperties& http_server_properties =
9171 *session->http_server_properties();
9172 AlternativeServiceVector alternative_service_vector =
9173 http_server_properties.GetAlternativeServices(http_host_port_pair);
9174 EXPECT_TRUE(alternative_service_vector.empty());
9175
9176 EXPECT_EQ(OK, callback.WaitForResult());
9177
9178 const HttpResponseInfo* response = trans->GetResponseInfo();
9179 ASSERT_TRUE(response != NULL);
9180 ASSERT_TRUE(response->headers.get() != NULL);
9181 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9182 EXPECT_FALSE(response->was_fetched_via_spdy);
9183 EXPECT_FALSE(response->was_npn_negotiated);
9184
9185 std::string response_data;
9186 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9187 EXPECT_EQ("hello world", response_data);
9188
9189 alternative_service_vector =
9190 http_server_properties.GetAlternativeServices(http_host_port_pair);
9191 ASSERT_EQ(1u, alternative_service_vector.size());
9192 EXPECT_EQ(AlternateProtocolFromNextProto(GetParam()),
9193 alternative_service_vector[0].protocol);
9194 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
9195 EXPECT_EQ(443, alternative_service_vector[0].port);
9196}
9197
bnc54ec34b72015-08-26 19:34:569198// When |use_alternative_services| is false, do not observe alternative service
9199// entries that point to a different host.
9200TEST_P(HttpNetworkTransactionTest, DisableAlternativeServiceToDifferentHost) {
9201 session_deps_.use_alternative_services = false;
9202
9203 HttpRequestInfo request;
9204 request.method = "GET";
9205 request.url = GURL("http://www.example.org/");
9206 request.load_flags = 0;
9207
9208 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
9209 StaticSocketDataProvider first_data;
9210 first_data.set_connect_data(mock_connect);
9211 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
9212
9213 MockRead data_reads[] = {
9214 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
9215 MockRead(ASYNC, OK),
9216 };
9217 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads),
9218 nullptr, 0);
9219 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
9220
9221 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9222
9223 base::WeakPtr<HttpServerProperties> http_server_properties =
9224 session->http_server_properties();
9225 AlternativeService alternative_service(
9226 AlternateProtocolFromNextProto(GetParam()), "different.example.org", 80);
9227 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9228 http_server_properties->SetAlternativeService(
9229 HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
9230
9231 scoped_ptr<HttpTransaction> trans(
9232 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9233 TestCompletionCallback callback;
9234
9235 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9236 // The connetion to origin was refused, and the alternative service should not
9237 // be used (even though mock data are there), therefore the request should
9238 // fail.
9239 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
9240}
9241
[email protected]23e482282013-06-14 16:08:029242TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239243 MarkBrokenAlternateProtocolAndFallback) {
bnc55ff9da2015-08-19 18:42:359244 session_deps_.use_alternative_services = true;
[email protected]564b4912010-03-09 16:30:429245
9246 HttpRequestInfo request;
9247 request.method = "GET";
bncce36dca22015-04-21 22:11:239248 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:429249 request.load_flags = 0;
9250
[email protected]d973e99a2012-02-17 21:02:369251 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:429252 StaticSocketDataProvider first_data;
9253 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079254 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:429255
9256 MockRead data_reads[] = {
9257 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9258 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069259 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:429260 };
9261 StaticSocketDataProvider second_data(
9262 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079263 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:429264
[email protected]bb88e1d32013-05-03 23:11:079265 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:429266
[email protected]30d4c022013-07-18 22:58:169267 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539268 session->http_server_properties();
bnc8445b3002015-03-13 01:57:099269 const HostPortPair host_port_pair = HostPortPair::FromURL(request.url);
[email protected]3912662a32011-10-04 00:51:119270 // Port must be < 1024, or the header will be ignored (since initial port was
9271 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:109272 const AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239273 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bncd9b132e2015-07-08 05:16:109274 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:129275 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
9276 http_server_properties->SetAlternativeService(
9277 host_port_pair, alternative_service, 1.0, expiration);
[email protected]564b4912010-03-09 16:30:429278
[email protected]262eec82013-03-19 21:01:369279 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509280 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419281 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:429282
[email protected]49639fa2011-12-20 23:22:419283 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:429284 EXPECT_EQ(ERR_IO_PENDING, rv);
9285 EXPECT_EQ(OK, callback.WaitForResult());
9286
9287 const HttpResponseInfo* response = trans->GetResponseInfo();
9288 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509289 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]564b4912010-03-09 16:30:429290 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9291
9292 std::string response_data;
9293 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9294 EXPECT_EQ("hello world", response_data);
9295
bncd9b132e2015-07-08 05:16:109296 const AlternativeServiceVector alternative_service_vector =
9297 http_server_properties->GetAlternativeServices(host_port_pair);
9298 ASSERT_EQ(1u, alternative_service_vector.size());
9299 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
9300 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
9301 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:429302}
9303
bnc55ff9da2015-08-19 18:42:359304// Ensure that we are not allowed to redirect traffic via an alternate protocol
9305// to an unrestricted (port >= 1024) when the original traffic was on a
9306// restricted port (port < 1024). Ensure that we can redirect in all other
9307// cases.
[email protected]23e482282013-06-14 16:08:029308TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239309 AlternateProtocolPortRestrictedBlocked) {
bnc55ff9da2015-08-19 18:42:359310 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119311
9312 HttpRequestInfo restricted_port_request;
9313 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239314 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119315 restricted_port_request.load_flags = 0;
9316
[email protected]d973e99a2012-02-17 21:02:369317 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119318 StaticSocketDataProvider first_data;
9319 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079320 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119321
9322 MockRead data_reads[] = {
9323 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9324 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069325 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119326 };
9327 StaticSocketDataProvider second_data(
9328 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079329 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119330
[email protected]bb88e1d32013-05-03 23:11:079331 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119332
[email protected]30d4c022013-07-18 22:58:169333 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539334 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119335 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229336 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239337 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229338 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129339 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229340 http_server_properties->SetAlternativeService(
9341 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129342 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119343
[email protected]262eec82013-03-19 21:01:369344 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509345 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419346 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119347
[email protected]49639fa2011-12-20 23:22:419348 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369349 &restricted_port_request,
9350 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119351 EXPECT_EQ(ERR_IO_PENDING, rv);
9352 // Invalid change to unrestricted port should fail.
9353 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:199354}
[email protected]3912662a32011-10-04 00:51:119355
bnc55ff9da2015-08-19 18:42:359356// Ensure that we are allowed to redirect traffic via an alternate protocol to
9357// an unrestricted (port >= 1024) when the original traffic was on a restricted
9358// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
[email protected]23e482282013-06-14 16:08:029359TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:199360 AlternateProtocolPortRestrictedPermitted) {
bnc55ff9da2015-08-19 18:42:359361 session_deps_.use_alternative_services = true;
[email protected]bb88e1d32013-05-03 23:11:079362 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:199363
9364 HttpRequestInfo restricted_port_request;
9365 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239366 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:199367 restricted_port_request.load_flags = 0;
9368
9369 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
9370 StaticSocketDataProvider first_data;
9371 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079372 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:199373
9374 MockRead data_reads[] = {
9375 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9376 MockRead("hello world"),
9377 MockRead(ASYNC, OK),
9378 };
9379 StaticSocketDataProvider second_data(
9380 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079381 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:199382
[email protected]bb88e1d32013-05-03 23:11:079383 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:199384
[email protected]30d4c022013-07-18 22:58:169385 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]c54c6962013-02-01 04:53:199386 session->http_server_properties();
9387 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:229388 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239389 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229390 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129391 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229392 http_server_properties->SetAlternativeService(
9393 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129394 1.0, expiration);
[email protected]c54c6962013-02-01 04:53:199395
[email protected]262eec82013-03-19 21:01:369396 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509397 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:199398 TestCompletionCallback callback;
9399
9400 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:369401 &restricted_port_request,
9402 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:199403 // Change to unrestricted port should succeed.
9404 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119405}
9406
bnc55ff9da2015-08-19 18:42:359407// Ensure that we are not allowed to redirect traffic via an alternate protocol
9408// to an unrestricted (port >= 1024) when the original traffic was on a
9409// restricted port (port < 1024). Ensure that we can redirect in all other
9410// cases.
[email protected]23e482282013-06-14 16:08:029411TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239412 AlternateProtocolPortRestrictedAllowed) {
bnc55ff9da2015-08-19 18:42:359413 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119414
9415 HttpRequestInfo restricted_port_request;
9416 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239417 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:119418 restricted_port_request.load_flags = 0;
9419
[email protected]d973e99a2012-02-17 21:02:369420 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119421 StaticSocketDataProvider first_data;
9422 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079423 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119424
9425 MockRead data_reads[] = {
9426 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9427 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069428 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119429 };
9430 StaticSocketDataProvider second_data(
9431 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079432 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119433
[email protected]bb88e1d32013-05-03 23:11:079434 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119435
[email protected]30d4c022013-07-18 22:58:169436 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539437 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119438 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229439 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239440 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229441 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129442 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229443 http_server_properties->SetAlternativeService(
9444 HostPortPair::FromURL(restricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129445 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119446
[email protected]262eec82013-03-19 21:01:369447 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509448 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419449 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119450
[email protected]49639fa2011-12-20 23:22:419451 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:369452 &restricted_port_request,
9453 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119454 EXPECT_EQ(ERR_IO_PENDING, rv);
9455 // Valid change to restricted port should pass.
9456 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119457}
9458
bnc55ff9da2015-08-19 18:42:359459// Ensure that we are not allowed to redirect traffic via an alternate protocol
9460// to an unrestricted (port >= 1024) when the original traffic was on a
9461// restricted port (port < 1024). Ensure that we can redirect in all other
9462// cases.
[email protected]23e482282013-06-14 16:08:029463TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239464 AlternateProtocolPortUnrestrictedAllowed1) {
bnc55ff9da2015-08-19 18:42:359465 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119466
9467 HttpRequestInfo unrestricted_port_request;
9468 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239469 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119470 unrestricted_port_request.load_flags = 0;
9471
[email protected]d973e99a2012-02-17 21:02:369472 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119473 StaticSocketDataProvider first_data;
9474 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079475 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119476
9477 MockRead data_reads[] = {
9478 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9479 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069480 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119481 };
9482 StaticSocketDataProvider second_data(
9483 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079484 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119485
[email protected]bb88e1d32013-05-03 23:11:079486 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119487
[email protected]30d4c022013-07-18 22:58:169488 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539489 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:119490 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:229491 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239492 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229493 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129494 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229495 http_server_properties->SetAlternativeService(
9496 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129497 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119498
[email protected]262eec82013-03-19 21:01:369499 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509500 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419501 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119502
[email protected]49639fa2011-12-20 23:22:419503 int rv = trans->Start(
9504 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119505 EXPECT_EQ(ERR_IO_PENDING, rv);
9506 // Valid change to restricted port should pass.
9507 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119508}
9509
bnc55ff9da2015-08-19 18:42:359510// Ensure that we are not allowed to redirect traffic via an alternate protocol
9511// to an unrestricted (port >= 1024) when the original traffic was on a
9512// restricted port (port < 1024). Ensure that we can redirect in all other
9513// cases.
[email protected]23e482282013-06-14 16:08:029514TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239515 AlternateProtocolPortUnrestrictedAllowed2) {
bnc55ff9da2015-08-19 18:42:359516 session_deps_.use_alternative_services = true;
[email protected]3912662a32011-10-04 00:51:119517
9518 HttpRequestInfo unrestricted_port_request;
9519 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:239520 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:119521 unrestricted_port_request.load_flags = 0;
9522
[email protected]d973e99a2012-02-17 21:02:369523 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:119524 StaticSocketDataProvider first_data;
9525 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:079526 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:119527
9528 MockRead data_reads[] = {
9529 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9530 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069531 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:119532 };
9533 StaticSocketDataProvider second_data(
9534 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079535 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:119536
[email protected]bb88e1d32013-05-03 23:11:079537 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:119538
[email protected]30d4c022013-07-18 22:58:169539 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]17291a022011-10-10 07:32:539540 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:229541 const int kUnrestrictedAlternatePort = 1025;
bnccacc0992015-03-20 20:22:229542 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239543 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229544 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:129545 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229546 http_server_properties->SetAlternativeService(
9547 HostPortPair::FromURL(unrestricted_port_request.url), alternative_service,
bnc7dc7e1b42015-07-28 14:43:129548 1.0, expiration);
[email protected]3912662a32011-10-04 00:51:119549
[email protected]262eec82013-03-19 21:01:369550 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509551 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:419552 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:119553
[email protected]49639fa2011-12-20 23:22:419554 int rv = trans->Start(
9555 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:119556 EXPECT_EQ(ERR_IO_PENDING, rv);
9557 // Valid change to an unrestricted port should pass.
9558 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:119559}
9560
bnc55ff9da2015-08-19 18:42:359561// Ensure that we are not allowed to redirect traffic via an alternate protocol
9562// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
9563// once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:239564TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
bnc55ff9da2015-08-19 18:42:359565 session_deps_.use_alternative_services = true;
[email protected]eb6234e2012-01-19 01:50:029566
9567 HttpRequestInfo request;
9568 request.method = "GET";
bncce36dca22015-04-21 22:11:239569 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:029570 request.load_flags = 0;
9571
9572 // The alternate protocol request will error out before we attempt to connect,
9573 // so only the standard HTTP request will try to connect.
9574 MockRead data_reads[] = {
9575 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
9576 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069577 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:029578 };
9579 StaticSocketDataProvider data(
9580 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079581 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:029582
[email protected]bb88e1d32013-05-03 23:11:079583 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:029584
[email protected]30d4c022013-07-18 22:58:169585 base::WeakPtr<HttpServerProperties> http_server_properties =
[email protected]eb6234e2012-01-19 01:50:029586 session->http_server_properties();
9587 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:229588 AlternativeService alternative_service(
bncce36dca22015-04-21 22:11:239589 AlternateProtocolFromNextProto(GetParam()), "www.example.org",
bnccacc0992015-03-20 20:22:229590 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:129591 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229592 http_server_properties->SetAlternativeService(
bnc7dc7e1b42015-07-28 14:43:129593 HostPortPair::FromURL(request.url), alternative_service, 1.0, expiration);
[email protected]eb6234e2012-01-19 01:50:029594
[email protected]262eec82013-03-19 21:01:369595 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509596 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:029597 TestCompletionCallback callback;
9598
9599 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9600 EXPECT_EQ(ERR_IO_PENDING, rv);
9601 // The HTTP request should succeed.
9602 EXPECT_EQ(OK, callback.WaitForResult());
9603
[email protected]eb6234e2012-01-19 01:50:029604 const HttpResponseInfo* response = trans->GetResponseInfo();
9605 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509606 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]eb6234e2012-01-19 01:50:029607 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9608
9609 std::string response_data;
9610 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9611 EXPECT_EQ("hello world", response_data);
9612}
9613
[email protected]23e482282013-06-14 16:08:029614TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
bnc55ff9da2015-08-19 18:42:359615 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:239616 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:549617
9618 HttpRequestInfo request;
9619 request.method = "GET";
bncce36dca22015-04-21 22:11:239620 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:549621 request.load_flags = 0;
9622
[email protected]8a0fc822013-06-27 20:52:439623 std::string alternate_protocol_http_header =
9624 GetAlternateProtocolHttpHeader();
9625
[email protected]2ff8b312010-04-26 22:20:549626 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529627 MockRead("HTTP/1.1 200 OK\r\n"),
9628 MockRead(alternate_protocol_http_header.c_str()),
9629 MockRead("\r\n"),
9630 MockRead("hello world"),
9631 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9632 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:549633
9634 StaticSocketDataProvider first_transaction(
9635 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079636 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:549637
[email protected]8ddf8322012-02-23 18:08:069638 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029639 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239640 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9641 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079642 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:549643
[email protected]cdf8f7e72013-05-23 10:56:469644 scoped_ptr<SpdyFrame> req(
9645 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:139646 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:549647
[email protected]23e482282013-06-14 16:08:029648 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9649 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:549650 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139651 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:549652 };
9653
rch8e6c6c42015-05-01 14:05:139654 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9655 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:079656 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:549657
[email protected]d973e99a2012-02-17 21:02:369658 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559659 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
9660 NULL, 0, NULL, 0);
9661 hanging_non_alternate_protocol_socket.set_connect_data(
9662 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079663 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559664 &hanging_non_alternate_protocol_socket);
9665
[email protected]49639fa2011-12-20 23:22:419666 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:549667
[email protected]bb88e1d32013-05-03 23:11:079668 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369669 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509670 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549671
[email protected]49639fa2011-12-20 23:22:419672 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549673 EXPECT_EQ(ERR_IO_PENDING, rv);
9674 EXPECT_EQ(OK, callback.WaitForResult());
9675
9676 const HttpResponseInfo* response = trans->GetResponseInfo();
9677 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509678 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549679 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9680
9681 std::string response_data;
9682 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9683 EXPECT_EQ("hello world", response_data);
9684
[email protected]90499482013-06-01 00:39:509685 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:549686
[email protected]49639fa2011-12-20 23:22:419687 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:549688 EXPECT_EQ(ERR_IO_PENDING, rv);
9689 EXPECT_EQ(OK, callback.WaitForResult());
9690
9691 response = trans->GetResponseInfo();
9692 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509693 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:549694 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:539695 EXPECT_TRUE(response->was_fetched_via_spdy);
9696 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:549697
9698 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9699 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:549700}
9701
[email protected]23e482282013-06-14 16:08:029702TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
bnc55ff9da2015-08-19 18:42:359703 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:239704 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559705
9706 HttpRequestInfo request;
9707 request.method = "GET";
bncce36dca22015-04-21 22:11:239708 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559709 request.load_flags = 0;
9710
[email protected]8a0fc822013-06-27 20:52:439711 std::string alternate_protocol_http_header =
9712 GetAlternateProtocolHttpHeader();
9713
[email protected]2d6728692011-03-12 01:39:559714 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529715 MockRead("HTTP/1.1 200 OK\r\n"),
9716 MockRead(alternate_protocol_http_header.c_str()),
9717 MockRead("\r\n"),
9718 MockRead("hello world"),
9719 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9720 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559721 };
9722
9723 StaticSocketDataProvider first_transaction(
9724 data_reads, arraysize(data_reads), NULL, 0);
9725 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:079726 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559727
[email protected]d973e99a2012-02-17 21:02:369728 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559729 StaticSocketDataProvider hanging_socket(
9730 NULL, 0, NULL, 0);
9731 hanging_socket.set_connect_data(never_finishing_connect);
9732 // Socket 2 and 3 are the hanging Alternate-Protocol and
9733 // non-Alternate-Protocol jobs from the 2nd transaction.
[email protected]bb88e1d32013-05-03 23:11:079734 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
9735 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559736
[email protected]8ddf8322012-02-23 18:08:069737 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029738 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239739 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9740 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079741 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559742
[email protected]cdf8f7e72013-05-23 10:56:469743 scoped_ptr<SpdyFrame> req1(
9744 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
9745 scoped_ptr<SpdyFrame> req2(
9746 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:559747 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139748 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:559749 };
[email protected]23e482282013-06-14 16:08:029750 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
9751 scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
9752 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
9753 scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:559754 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:139755 CreateMockRead(*resp1, 2),
9756 CreateMockRead(*data1, 3),
9757 CreateMockRead(*resp2, 4),
9758 CreateMockRead(*data2, 5),
9759 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:559760 };
9761
rch8e6c6c42015-05-01 14:05:139762 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
9763 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:559764 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079765 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:559766
9767 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:079768 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
[email protected]2d6728692011-03-12 01:39:559769
[email protected]bb88e1d32013-05-03 23:11:079770 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:419771 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:509772 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:559773
[email protected]49639fa2011-12-20 23:22:419774 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559775 EXPECT_EQ(ERR_IO_PENDING, rv);
9776 EXPECT_EQ(OK, callback1.WaitForResult());
9777
9778 const HttpResponseInfo* response = trans1.GetResponseInfo();
9779 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509780 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559781 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9782
9783 std::string response_data;
9784 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
9785 EXPECT_EQ("hello world", response_data);
9786
[email protected]49639fa2011-12-20 23:22:419787 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:509788 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419789 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559790 EXPECT_EQ(ERR_IO_PENDING, rv);
9791
[email protected]49639fa2011-12-20 23:22:419792 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:509793 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:419794 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559795 EXPECT_EQ(ERR_IO_PENDING, rv);
9796
9797 EXPECT_EQ(OK, callback2.WaitForResult());
9798 EXPECT_EQ(OK, callback3.WaitForResult());
9799
9800 response = trans2.GetResponseInfo();
9801 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509802 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559803 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9804 EXPECT_TRUE(response->was_fetched_via_spdy);
9805 EXPECT_TRUE(response->was_npn_negotiated);
9806 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
9807 EXPECT_EQ("hello!", response_data);
9808
9809 response = trans3.GetResponseInfo();
9810 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509811 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559812 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9813 EXPECT_TRUE(response->was_fetched_via_spdy);
9814 EXPECT_TRUE(response->was_npn_negotiated);
9815 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
9816 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:559817}
9818
[email protected]23e482282013-06-14 16:08:029819TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
bnc55ff9da2015-08-19 18:42:359820 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:239821 session_deps_.next_protos = SpdyNextProtos();
[email protected]2d6728692011-03-12 01:39:559822
9823 HttpRequestInfo request;
9824 request.method = "GET";
bncce36dca22015-04-21 22:11:239825 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:559826 request.load_flags = 0;
9827
[email protected]8a0fc822013-06-27 20:52:439828 std::string alternate_protocol_http_header =
9829 GetAlternateProtocolHttpHeader();
9830
[email protected]2d6728692011-03-12 01:39:559831 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529832 MockRead("HTTP/1.1 200 OK\r\n"),
9833 MockRead(alternate_protocol_http_header.c_str()),
9834 MockRead("\r\n"),
9835 MockRead("hello world"),
9836 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9837 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:559838 };
9839
9840 StaticSocketDataProvider first_transaction(
9841 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079842 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559843
[email protected]8ddf8322012-02-23 18:08:069844 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029845 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:079846 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:559847
[email protected]d973e99a2012-02-17 21:02:369848 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:559849 StaticSocketDataProvider hanging_alternate_protocol_socket(
9850 NULL, 0, NULL, 0);
9851 hanging_alternate_protocol_socket.set_connect_data(
9852 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:079853 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:559854 &hanging_alternate_protocol_socket);
9855
9856 // 2nd request is just a copy of the first one, over HTTP again.
[email protected]bb88e1d32013-05-03 23:11:079857 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:559858
[email protected]49639fa2011-12-20 23:22:419859 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:559860
[email protected]bb88e1d32013-05-03 23:11:079861 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:369862 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509863 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559864
[email protected]49639fa2011-12-20 23:22:419865 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559866 EXPECT_EQ(ERR_IO_PENDING, rv);
9867 EXPECT_EQ(OK, callback.WaitForResult());
9868
9869 const HttpResponseInfo* response = trans->GetResponseInfo();
9870 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509871 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559872 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9873
9874 std::string response_data;
9875 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9876 EXPECT_EQ("hello world", response_data);
9877
[email protected]90499482013-06-01 00:39:509878 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:559879
[email protected]49639fa2011-12-20 23:22:419880 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:559881 EXPECT_EQ(ERR_IO_PENDING, rv);
9882 EXPECT_EQ(OK, callback.WaitForResult());
9883
9884 response = trans->GetResponseInfo();
9885 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:509886 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2d6728692011-03-12 01:39:559887 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9888 EXPECT_FALSE(response->was_fetched_via_spdy);
9889 EXPECT_FALSE(response->was_npn_negotiated);
9890
9891 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9892 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:559893}
9894
[email protected]631f1322010-04-30 17:59:119895class CapturingProxyResolver : public ProxyResolver {
9896 public:
sammce90c9212015-05-27 23:43:359897 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:209898 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:119899
dchengb03027d2014-10-21 12:00:209900 int GetProxyForURL(const GURL& url,
9901 ProxyInfo* results,
9902 const CompletionCallback& callback,
9903 RequestHandle* request,
9904 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:409905 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
9906 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:429907 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:119908 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:429909 return OK;
[email protected]631f1322010-04-30 17:59:119910 }
9911
dchengb03027d2014-10-21 12:00:209912 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
[email protected]631f1322010-04-30 17:59:119913
dchengb03027d2014-10-21 12:00:209914 LoadState GetLoadState(RequestHandle request) const override {
[email protected]f2c971f2011-11-08 00:33:179915 NOTREACHED();
9916 return LOAD_STATE_IDLE;
9917 }
9918
[email protected]24476402010-07-20 20:55:179919 const std::vector<GURL>& resolved() const { return resolved_; }
9920
9921 private:
[email protected]631f1322010-04-30 17:59:119922 std::vector<GURL> resolved_;
9923
9924 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
9925};
9926
sammce64b2362015-04-29 03:50:239927class CapturingProxyResolverFactory : public ProxyResolverFactory {
9928 public:
9929 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
9930 : ProxyResolverFactory(false), resolver_(resolver) {}
9931
9932 int CreateProxyResolver(
9933 const scoped_refptr<ProxyResolverScriptData>& pac_script,
9934 scoped_ptr<ProxyResolver>* resolver,
9935 const net::CompletionCallback& callback,
9936 scoped_ptr<Request>* request) override {
9937 resolver->reset(new ForwardingProxyResolver(resolver_));
9938 return OK;
9939 }
9940
9941 private:
9942 ProxyResolver* resolver_;
9943};
9944
[email protected]23e482282013-06-14 16:08:029945TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:239946 UseAlternateProtocolForTunneledNpnSpdy) {
bnc55ff9da2015-08-19 18:42:359947 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:239948 session_deps_.next_protos = SpdyNextProtos();
[email protected]631f1322010-04-30 17:59:119949
9950 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:429951 proxy_config.set_auto_detect(true);
9952 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:119953
sammc5dd160c2015-04-02 02:43:139954 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:079955 session_deps_.proxy_service.reset(new ProxyService(
sammc5dd160c2015-04-02 02:43:139956 new ProxyConfigServiceFixed(proxy_config),
9957 make_scoped_ptr(
sammce64b2362015-04-29 03:50:239958 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:389959 NULL));
vishal.b62985ca92015-04-17 08:45:519960 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079961 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:119962
9963 HttpRequestInfo request;
9964 request.method = "GET";
bncce36dca22015-04-21 22:11:239965 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:119966 request.load_flags = 0;
9967
[email protected]8a0fc822013-06-27 20:52:439968 std::string alternate_protocol_http_header =
9969 GetAlternateProtocolHttpHeader();
9970
[email protected]631f1322010-04-30 17:59:119971 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:529972 MockRead("HTTP/1.1 200 OK\r\n"),
9973 MockRead(alternate_protocol_http_header.c_str()),
9974 MockRead("\r\n"),
9975 MockRead("hello world"),
9976 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
9977 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:119978 };
9979
9980 StaticSocketDataProvider first_transaction(
9981 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079982 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:119983
[email protected]8ddf8322012-02-23 18:08:069984 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:029985 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:239986 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
9987 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:079988 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:119989
[email protected]cdf8f7e72013-05-23 10:56:469990 scoped_ptr<SpdyFrame> req(
9991 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:119992 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:139993 MockWrite(ASYNC, 0,
9994 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9995 "Host: www.example.org\r\n"
9996 "Proxy-Connection: keep-alive\r\n\r\n"),
9997 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:119998 };
9999
[email protected]d911f1b2010-05-05 22:39:4210000 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
10001
[email protected]23e482282013-06-14 16:08:0210002 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10003 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:1110004 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310005 MockRead(ASYNC, 1, kCONNECTResponse),
10006 CreateMockRead(*resp.get(), 3),
10007 CreateMockRead(*data.get(), 4),
10008 MockRead(ASYNC, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1110009 };
10010
rch8e6c6c42015-05-01 14:05:1310011 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10012 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710013 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1110014
[email protected]d973e99a2012-02-17 21:02:3610015 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510016 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10017 NULL, 0, NULL, 0);
10018 hanging_non_alternate_protocol_socket.set_connect_data(
10019 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710020 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510021 &hanging_non_alternate_protocol_socket);
10022
[email protected]49639fa2011-12-20 23:22:4110023 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1110024
[email protected]bb88e1d32013-05-03 23:11:0710025 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610026 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010027 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1110028
[email protected]49639fa2011-12-20 23:22:4110029 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1110030 EXPECT_EQ(ERR_IO_PENDING, rv);
10031 EXPECT_EQ(OK, callback.WaitForResult());
10032
10033 const HttpResponseInfo* response = trans->GetResponseInfo();
10034 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010035 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:1110036 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310037 EXPECT_FALSE(response->was_fetched_via_spdy);
10038 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1110039
10040 std::string response_data;
10041 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10042 EXPECT_EQ("hello world", response_data);
10043
[email protected]90499482013-06-01 00:39:5010044 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1110045
[email protected]49639fa2011-12-20 23:22:4110046 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1110047 EXPECT_EQ(ERR_IO_PENDING, rv);
10048 EXPECT_EQ(OK, callback.WaitForResult());
10049
10050 response = trans->GetResponseInfo();
10051 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010052 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]631f1322010-04-30 17:59:1110053 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310054 EXPECT_TRUE(response->was_fetched_via_spdy);
10055 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1110056
10057 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10058 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:1310059 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:2310060 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:1310061 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2310062 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1310063 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1110064
[email protected]029c83b62013-01-24 05:28:2010065 LoadTimingInfo load_timing_info;
10066 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10067 TestLoadTimingNotReusedWithPac(load_timing_info,
10068 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1110069}
[email protected]631f1322010-04-30 17:59:1110070
[email protected]23e482282013-06-14 16:08:0210071TEST_P(HttpNetworkTransactionTest,
[email protected]2ff8b312010-04-26 22:20:5410072 UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
bnc55ff9da2015-08-19 18:42:3510073 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310074 session_deps_.next_protos = SpdyNextProtos();
[email protected]2ff8b312010-04-26 22:20:5410075
10076 HttpRequestInfo request;
10077 request.method = "GET";
bncce36dca22015-04-21 22:11:2310078 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410079 request.load_flags = 0;
10080
[email protected]8a0fc822013-06-27 20:52:4310081 std::string alternate_protocol_http_header =
10082 GetAlternateProtocolHttpHeader();
10083
[email protected]2ff8b312010-04-26 22:20:5410084 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210085 MockRead("HTTP/1.1 200 OK\r\n"),
10086 MockRead(alternate_protocol_http_header.c_str()),
10087 MockRead("\r\n"),
10088 MockRead("hello world"),
10089 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5410090 };
10091
10092 StaticSocketDataProvider first_transaction(
10093 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710094 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5410095
[email protected]8ddf8322012-02-23 18:08:0610096 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210097 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2310098 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10099 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710100 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5410101
[email protected]cdf8f7e72013-05-23 10:56:4610102 scoped_ptr<SpdyFrame> req(
10103 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310104 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410105
[email protected]23e482282013-06-14 16:08:0210106 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10107 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410108 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310109 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410110 };
10111
rch8e6c6c42015-05-01 14:05:1310112 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10113 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710114 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410115
[email protected]83039bb2011-12-09 18:43:5510116 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410117
[email protected]bb88e1d32013-05-03 23:11:0710118 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5410119
[email protected]262eec82013-03-19 21:01:3610120 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010121 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410122
[email protected]49639fa2011-12-20 23:22:4110123 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410124 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110125 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5410126
10127 const HttpResponseInfo* response = trans->GetResponseInfo();
10128 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010129 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410130 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10131
10132 std::string response_data;
10133 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10134 EXPECT_EQ("hello world", response_data);
10135
10136 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2310137 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4010138 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5310139 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2710140 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2610141 CreateSecureSpdySession(session, key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:3810142
[email protected]90499482013-06-01 00:39:5010143 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410144
[email protected]49639fa2011-12-20 23:22:4110145 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410146 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4110147 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5410148
10149 response = trans->GetResponseInfo();
10150 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010151 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]2ff8b312010-04-26 22:20:5410152 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310153 EXPECT_TRUE(response->was_fetched_via_spdy);
10154 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410155
10156 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10157 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4210158}
10159
[email protected]044de0642010-06-17 10:42:1510160// GenerateAuthToken is a mighty big test.
10161// It tests all permutation of GenerateAuthToken behavior:
10162// - Synchronous and Asynchronous completion.
10163// - OK or error on completion.
10164// - Direct connection, non-authenticating proxy, and authenticating proxy.
10165// - HTTP or HTTPS backend (to include proxy tunneling).
10166// - Non-authenticating and authenticating backend.
10167//
[email protected]fe3b7dc2012-02-03 19:52:0910168// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1510169// problems generating an auth token for an authenticating proxy, we don't
10170// need to test all permutations of the backend server).
10171//
10172// The test proceeds by going over each of the configuration cases, and
10173// potentially running up to three rounds in each of the tests. The TestConfig
10174// specifies both the configuration for the test as well as the expectations
10175// for the results.
[email protected]23e482282013-06-14 16:08:0210176TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5010177 static const char kServer[] = "http://www.example.com";
10178 static const char kSecureServer[] = "https://www.example.com";
10179 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1510180 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
10181
10182 enum AuthTiming {
10183 AUTH_NONE,
10184 AUTH_SYNC,
10185 AUTH_ASYNC,
10186 };
10187
10188 const MockWrite kGet(
10189 "GET / HTTP/1.1\r\n"
10190 "Host: www.example.com\r\n"
10191 "Connection: keep-alive\r\n\r\n");
10192 const MockWrite kGetProxy(
10193 "GET http://www.example.com/ HTTP/1.1\r\n"
10194 "Host: www.example.com\r\n"
10195 "Proxy-Connection: keep-alive\r\n\r\n");
10196 const MockWrite kGetAuth(
10197 "GET / HTTP/1.1\r\n"
10198 "Host: www.example.com\r\n"
10199 "Connection: keep-alive\r\n"
10200 "Authorization: auth_token\r\n\r\n");
10201 const MockWrite kGetProxyAuth(
10202 "GET http://www.example.com/ HTTP/1.1\r\n"
10203 "Host: www.example.com\r\n"
10204 "Proxy-Connection: keep-alive\r\n"
10205 "Proxy-Authorization: auth_token\r\n\r\n");
10206 const MockWrite kGetAuthThroughProxy(
10207 "GET http://www.example.com/ HTTP/1.1\r\n"
10208 "Host: www.example.com\r\n"
10209 "Proxy-Connection: keep-alive\r\n"
10210 "Authorization: auth_token\r\n\r\n");
10211 const MockWrite kGetAuthWithProxyAuth(
10212 "GET http://www.example.com/ HTTP/1.1\r\n"
10213 "Host: www.example.com\r\n"
10214 "Proxy-Connection: keep-alive\r\n"
10215 "Proxy-Authorization: auth_token\r\n"
10216 "Authorization: auth_token\r\n\r\n");
10217 const MockWrite kConnect(
10218 "CONNECT www.example.com:443 HTTP/1.1\r\n"
10219 "Host: www.example.com\r\n"
10220 "Proxy-Connection: keep-alive\r\n\r\n");
10221 const MockWrite kConnectProxyAuth(
10222 "CONNECT www.example.com:443 HTTP/1.1\r\n"
10223 "Host: www.example.com\r\n"
10224 "Proxy-Connection: keep-alive\r\n"
10225 "Proxy-Authorization: auth_token\r\n\r\n");
10226
10227 const MockRead kSuccess(
10228 "HTTP/1.1 200 OK\r\n"
10229 "Content-Type: text/html; charset=iso-8859-1\r\n"
10230 "Content-Length: 3\r\n\r\n"
10231 "Yes");
10232 const MockRead kFailure(
10233 "Should not be called.");
10234 const MockRead kServerChallenge(
10235 "HTTP/1.1 401 Unauthorized\r\n"
10236 "WWW-Authenticate: Mock realm=server\r\n"
10237 "Content-Type: text/html; charset=iso-8859-1\r\n"
10238 "Content-Length: 14\r\n\r\n"
10239 "Unauthorized\r\n");
10240 const MockRead kProxyChallenge(
10241 "HTTP/1.1 407 Unauthorized\r\n"
10242 "Proxy-Authenticate: Mock realm=proxy\r\n"
10243 "Proxy-Connection: close\r\n"
10244 "Content-Type: text/html; charset=iso-8859-1\r\n"
10245 "Content-Length: 14\r\n\r\n"
10246 "Unauthorized\r\n");
10247 const MockRead kProxyConnected(
10248 "HTTP/1.1 200 Connection Established\r\n\r\n");
10249
10250 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
10251 // no constructors, but the C++ compiler on Windows warns about
10252 // unspecified data in compound literals. So, moved to using constructors,
10253 // and TestRound's created with the default constructor should not be used.
10254 struct TestRound {
10255 TestRound()
10256 : expected_rv(ERR_UNEXPECTED),
10257 extra_write(NULL),
10258 extra_read(NULL) {
10259 }
10260 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
10261 int expected_rv_arg)
10262 : write(write_arg),
10263 read(read_arg),
10264 expected_rv(expected_rv_arg),
10265 extra_write(NULL),
10266 extra_read(NULL) {
10267 }
10268 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
10269 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0110270 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1510271 : write(write_arg),
10272 read(read_arg),
10273 expected_rv(expected_rv_arg),
10274 extra_write(extra_write_arg),
10275 extra_read(extra_read_arg) {
10276 }
10277 MockWrite write;
10278 MockRead read;
10279 int expected_rv;
10280 const MockWrite* extra_write;
10281 const MockRead* extra_read;
10282 };
10283
10284 static const int kNoSSL = 500;
10285
10286 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:5110287 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1510288 AuthTiming proxy_auth_timing;
10289 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:5110290 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1510291 AuthTiming server_auth_timing;
10292 int server_auth_rv;
10293 int num_auth_rounds;
10294 int first_ssl_round;
10295 TestRound rounds[3];
10296 } test_configs[] = {
10297 // Non-authenticating HTTP server with a direct connection.
10298 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
10299 { TestRound(kGet, kSuccess, OK)}},
10300 // Authenticating HTTP server with a direct connection.
10301 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
10302 { TestRound(kGet, kServerChallenge, OK),
10303 TestRound(kGetAuth, kSuccess, OK)}},
10304 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
10305 { TestRound(kGet, kServerChallenge, OK),
10306 TestRound(kGetAuth, kFailure, kAuthErr)}},
10307 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
10308 { TestRound(kGet, kServerChallenge, OK),
10309 TestRound(kGetAuth, kSuccess, OK)}},
10310 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
10311 { TestRound(kGet, kServerChallenge, OK),
10312 TestRound(kGetAuth, kFailure, kAuthErr)}},
10313 // Non-authenticating HTTP server through a non-authenticating proxy.
10314 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
10315 { TestRound(kGetProxy, kSuccess, OK)}},
10316 // Authenticating HTTP server through a non-authenticating proxy.
10317 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
10318 { TestRound(kGetProxy, kServerChallenge, OK),
10319 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
10320 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
10321 { TestRound(kGetProxy, kServerChallenge, OK),
10322 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
10323 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
10324 { TestRound(kGetProxy, kServerChallenge, OK),
10325 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
10326 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
10327 { TestRound(kGetProxy, kServerChallenge, OK),
10328 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
10329 // Non-authenticating HTTP server through an authenticating proxy.
10330 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
10331 { TestRound(kGetProxy, kProxyChallenge, OK),
10332 TestRound(kGetProxyAuth, kSuccess, OK)}},
10333 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
10334 { TestRound(kGetProxy, kProxyChallenge, OK),
10335 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
10336 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
10337 { TestRound(kGetProxy, kProxyChallenge, OK),
10338 TestRound(kGetProxyAuth, kSuccess, OK)}},
10339 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
10340 { TestRound(kGetProxy, kProxyChallenge, OK),
10341 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
10342 // Authenticating HTTP server through an authenticating proxy.
10343 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
10344 { TestRound(kGetProxy, kProxyChallenge, OK),
10345 TestRound(kGetProxyAuth, kServerChallenge, OK),
10346 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10347 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
10348 { TestRound(kGetProxy, kProxyChallenge, OK),
10349 TestRound(kGetProxyAuth, kServerChallenge, OK),
10350 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10351 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
10352 { TestRound(kGetProxy, kProxyChallenge, OK),
10353 TestRound(kGetProxyAuth, kServerChallenge, OK),
10354 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10355 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
10356 { TestRound(kGetProxy, kProxyChallenge, OK),
10357 TestRound(kGetProxyAuth, kServerChallenge, OK),
10358 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10359 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
10360 { TestRound(kGetProxy, kProxyChallenge, OK),
10361 TestRound(kGetProxyAuth, kServerChallenge, OK),
10362 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10363 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
10364 { TestRound(kGetProxy, kProxyChallenge, OK),
10365 TestRound(kGetProxyAuth, kServerChallenge, OK),
10366 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10367 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
10368 { TestRound(kGetProxy, kProxyChallenge, OK),
10369 TestRound(kGetProxyAuth, kServerChallenge, OK),
10370 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
10371 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
10372 { TestRound(kGetProxy, kProxyChallenge, OK),
10373 TestRound(kGetProxyAuth, kServerChallenge, OK),
10374 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
10375 // Non-authenticating HTTPS server with a direct connection.
10376 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
10377 { TestRound(kGet, kSuccess, OK)}},
10378 // Authenticating HTTPS server with a direct connection.
10379 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
10380 { TestRound(kGet, kServerChallenge, OK),
10381 TestRound(kGetAuth, kSuccess, OK)}},
10382 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
10383 { TestRound(kGet, kServerChallenge, OK),
10384 TestRound(kGetAuth, kFailure, kAuthErr)}},
10385 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
10386 { TestRound(kGet, kServerChallenge, OK),
10387 TestRound(kGetAuth, kSuccess, OK)}},
10388 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
10389 { TestRound(kGet, kServerChallenge, OK),
10390 TestRound(kGetAuth, kFailure, kAuthErr)}},
10391 // Non-authenticating HTTPS server with a non-authenticating proxy.
10392 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
10393 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
10394 // Authenticating HTTPS server through a non-authenticating proxy.
10395 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
10396 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10397 TestRound(kGetAuth, kSuccess, OK)}},
10398 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
10399 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10400 TestRound(kGetAuth, kFailure, kAuthErr)}},
10401 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
10402 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10403 TestRound(kGetAuth, kSuccess, OK)}},
10404 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
10405 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
10406 TestRound(kGetAuth, kFailure, kAuthErr)}},
10407 // Non-Authenticating HTTPS server through an authenticating proxy.
10408 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10409 { TestRound(kConnect, kProxyChallenge, OK),
10410 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10411 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10412 { TestRound(kConnect, kProxyChallenge, OK),
10413 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10414 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
10415 { TestRound(kConnect, kProxyChallenge, OK),
10416 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
10417 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
10418 { TestRound(kConnect, kProxyChallenge, OK),
10419 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
10420 // Authenticating HTTPS server through an authenticating proxy.
10421 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10422 { TestRound(kConnect, kProxyChallenge, OK),
10423 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10424 &kGet, &kServerChallenge),
10425 TestRound(kGetAuth, kSuccess, OK)}},
10426 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10427 { TestRound(kConnect, kProxyChallenge, OK),
10428 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10429 &kGet, &kServerChallenge),
10430 TestRound(kGetAuth, kFailure, kAuthErr)}},
10431 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
10432 { TestRound(kConnect, kProxyChallenge, OK),
10433 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10434 &kGet, &kServerChallenge),
10435 TestRound(kGetAuth, kSuccess, OK)}},
10436 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
10437 { TestRound(kConnect, kProxyChallenge, OK),
10438 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10439 &kGet, &kServerChallenge),
10440 TestRound(kGetAuth, kFailure, kAuthErr)}},
10441 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10442 { TestRound(kConnect, kProxyChallenge, OK),
10443 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10444 &kGet, &kServerChallenge),
10445 TestRound(kGetAuth, kSuccess, OK)}},
10446 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10447 { TestRound(kConnect, kProxyChallenge, OK),
10448 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10449 &kGet, &kServerChallenge),
10450 TestRound(kGetAuth, kFailure, kAuthErr)}},
10451 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
10452 { TestRound(kConnect, kProxyChallenge, OK),
10453 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10454 &kGet, &kServerChallenge),
10455 TestRound(kGetAuth, kSuccess, OK)}},
10456 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
10457 { TestRound(kConnect, kProxyChallenge, OK),
10458 TestRound(kConnectProxyAuth, kProxyConnected, OK,
10459 &kGet, &kServerChallenge),
10460 TestRound(kGetAuth, kFailure, kAuthErr)}},
10461 };
10462
viettrungluue4a8b882014-10-16 06:17:3810463 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0810464 HttpAuthHandlerMock::Factory* auth_factory(
10465 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710466 session_deps_.http_auth_handler_factory.reset(auth_factory);
[email protected]044de0642010-06-17 10:42:1510467 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2610468
10469 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1510470 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0810471 for (int n = 0; n < 2; n++) {
10472 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10473 std::string auth_challenge = "Mock realm=proxy";
10474 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2410475 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10476 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0810477 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
10478 origin, BoundNetLog());
10479 auth_handler->SetGenerateExpectation(
10480 test_config.proxy_auth_timing == AUTH_ASYNC,
10481 test_config.proxy_auth_rv);
10482 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10483 }
[email protected]044de0642010-06-17 10:42:1510484 }
10485 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0010486 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1510487 std::string auth_challenge = "Mock realm=server";
10488 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2410489 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10490 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1510491 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10492 origin, BoundNetLog());
10493 auth_handler->SetGenerateExpectation(
10494 test_config.server_auth_timing == AUTH_ASYNC,
10495 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0810496 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1510497 }
10498 if (test_config.proxy_url) {
[email protected]bb88e1d32013-05-03 23:11:0710499 session_deps_.proxy_service.reset(
[email protected]6104ea5d2011-04-27 21:37:1210500 ProxyService::CreateFixed(test_config.proxy_url));
[email protected]044de0642010-06-17 10:42:1510501 } else {
[email protected]bb88e1d32013-05-03 23:11:0710502 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
[email protected]044de0642010-06-17 10:42:1510503 }
10504
10505 HttpRequestInfo request;
10506 request.method = "GET";
10507 request.url = GURL(test_config.server_url);
10508 request.load_flags = 0;
10509
[email protected]bb88e1d32013-05-03 23:11:0710510 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
dcheng48459ac22014-08-26 00:46:4110511 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]044de0642010-06-17 10:42:1510512
rchcb68dc62015-05-21 04:45:3610513 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
10514
10515 std::vector<std::vector<MockRead>> mock_reads(1);
10516 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1510517 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10518 const TestRound& read_write_round = test_config.rounds[round];
10519
10520 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3610521 mock_reads.back().push_back(read_write_round.read);
10522 mock_writes.back().push_back(read_write_round.write);
10523
10524 // kProxyChallenge uses Proxy-Connection: close which means that the
10525 // socket is closed and a new one will be created for the next request.
mmenkee0b5c882015-08-26 20:29:1110526 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3610527 mock_reads.push_back(std::vector<MockRead>());
10528 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1510529 }
10530
rchcb68dc62015-05-21 04:45:3610531 if (read_write_round.extra_read) {
10532 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1510533 }
rchcb68dc62015-05-21 04:45:3610534 if (read_write_round.extra_write) {
10535 mock_writes.back().push_back(*read_write_round.extra_write);
10536 }
[email protected]044de0642010-06-17 10:42:1510537
10538 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1510539 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0710540 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1510541 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3610542 }
[email protected]044de0642010-06-17 10:42:1510543
rchcb68dc62015-05-21 04:45:3610544 ScopedVector<StaticSocketDataProvider> data_providers;
10545 for (size_t i = 0; i < mock_reads.size(); ++i) {
10546 data_providers.push_back(new StaticSocketDataProvider(
10547 vector_as_array(&mock_reads[i]), mock_reads[i].size(),
10548 vector_as_array(&mock_writes[i]), mock_writes[i].size()));
10549 session_deps_.socket_factory->AddSocketDataProvider(
10550 data_providers.back());
10551 }
10552
10553 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
10554 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1510555 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4110556 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1510557 int rv;
10558 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4110559 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1510560 } else {
[email protected]49639fa2011-12-20 23:22:4110561 rv = trans.RestartWithAuth(
10562 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1510563 }
10564 if (rv == ERR_IO_PENDING)
10565 rv = callback.WaitForResult();
10566
10567 // Compare results with expected data.
10568 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5010569 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5510570 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1510571 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
10572 continue;
10573 }
10574 if (round + 1 < test_config.num_auth_rounds) {
10575 EXPECT_FALSE(response->auth_challenge.get() == NULL);
10576 } else {
10577 EXPECT_TRUE(response->auth_challenge.get() == NULL);
10578 }
10579 }
[email protected]e5ae96a2010-04-14 20:12:4510580 }
10581}
10582
[email protected]23e482282013-06-14 16:08:0210583TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1410584 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1410585 HttpAuthHandlerMock::Factory* auth_factory(
10586 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0710587 session_deps_.http_auth_handler_factory.reset(auth_factory);
10588 session_deps_.proxy_service.reset(ProxyService::CreateDirect());
10589 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
10590 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1410591
10592 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
10593 auth_handler->set_connection_based(true);
10594 std::string auth_challenge = "Mock realm=server";
10595 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2410596 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
10597 auth_challenge.end());
[email protected]c871bce92010-07-15 21:51:1410598 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
10599 origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0810600 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1410601
[email protected]c871bce92010-07-15 21:51:1410602 int rv = OK;
10603 const HttpResponseInfo* response = NULL;
10604 HttpRequestInfo request;
10605 request.method = "GET";
10606 request.url = origin;
10607 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2710608
[email protected]bb88e1d32013-05-03 23:11:0710609 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1010610
10611 // Use a TCP Socket Pool with only one connection per group. This is used
10612 // to validate that the TCP socket is not released to the pool between
10613 // each round of multi-round authentication.
10614 HttpNetworkSessionPeer session_peer(session);
[email protected]ab739042011-04-07 15:22:2810615 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1010616 50, // Max sockets for pool
10617 1, // Max sockets per group
[email protected]bb88e1d32013-05-03 23:11:0710618 session_deps_.host_resolver.get(),
10619 session_deps_.socket_factory.get(),
10620 session_deps_.net_log);
[email protected]831e4a32013-11-14 02:14:4410621 scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
10622 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0210623 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchenge3d1ddc2014-10-15 19:30:5110624 session_peer.SetClientSocketPoolManager(mock_pool_manager.Pass());
[email protected]7ef4cbbb2011-02-06 11:19:1010625
[email protected]262eec82013-03-19 21:01:3610626 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010627 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110628 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1410629
10630 const MockWrite kGet(
10631 "GET / HTTP/1.1\r\n"
10632 "Host: www.example.com\r\n"
10633 "Connection: keep-alive\r\n\r\n");
10634 const MockWrite kGetAuth(
10635 "GET / HTTP/1.1\r\n"
10636 "Host: www.example.com\r\n"
10637 "Connection: keep-alive\r\n"
10638 "Authorization: auth_token\r\n\r\n");
10639
10640 const MockRead kServerChallenge(
10641 "HTTP/1.1 401 Unauthorized\r\n"
10642 "WWW-Authenticate: Mock realm=server\r\n"
10643 "Content-Type: text/html; charset=iso-8859-1\r\n"
10644 "Content-Length: 14\r\n\r\n"
10645 "Unauthorized\r\n");
10646 const MockRead kSuccess(
10647 "HTTP/1.1 200 OK\r\n"
10648 "Content-Type: text/html; charset=iso-8859-1\r\n"
10649 "Content-Length: 3\r\n\r\n"
10650 "Yes");
10651
10652 MockWrite writes[] = {
10653 // First round
10654 kGet,
10655 // Second round
10656 kGetAuth,
10657 // Third round
10658 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3010659 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1010660 kGetAuth,
10661 // Competing request
10662 kGet,
[email protected]c871bce92010-07-15 21:51:1410663 };
10664 MockRead reads[] = {
10665 // First round
10666 kServerChallenge,
10667 // Second round
10668 kServerChallenge,
10669 // Third round
[email protected]eca50e122010-09-11 14:03:3010670 kServerChallenge,
10671 // Fourth round
[email protected]c871bce92010-07-15 21:51:1410672 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1010673 // Competing response
10674 kSuccess,
[email protected]c871bce92010-07-15 21:51:1410675 };
10676 StaticSocketDataProvider data_provider(reads, arraysize(reads),
10677 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0710678 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1410679
thestig9d3bb0c2015-01-24 00:49:5110680 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1010681
10682 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1410683 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110684 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1410685 if (rv == ERR_IO_PENDING)
10686 rv = callback.WaitForResult();
10687 EXPECT_EQ(OK, rv);
10688 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010689 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410690 EXPECT_FALSE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810691 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410692
[email protected]7ef4cbbb2011-02-06 11:19:1010693 // In between rounds, another request comes in for the same domain.
10694 // It should not be able to grab the TCP socket that trans has already
10695 // claimed.
10696 scoped_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5010697 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110698 TestCompletionCallback callback_compete;
10699 rv = trans_compete->Start(
10700 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1010701 EXPECT_EQ(ERR_IO_PENDING, rv);
10702 // callback_compete.WaitForResult at this point would stall forever,
10703 // since the HttpNetworkTransaction does not release the request back to
10704 // the pool until after authentication completes.
10705
10706 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1410707 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110708 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410709 if (rv == ERR_IO_PENDING)
10710 rv = callback.WaitForResult();
10711 EXPECT_EQ(OK, rv);
10712 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010713 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410714 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810715 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410716
[email protected]7ef4cbbb2011-02-06 11:19:1010717 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1410718 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110719 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1410720 if (rv == ERR_IO_PENDING)
10721 rv = callback.WaitForResult();
10722 EXPECT_EQ(OK, rv);
10723 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010724 ASSERT_TRUE(response != NULL);
[email protected]c871bce92010-07-15 21:51:1410725 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810726 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3010727
[email protected]7ef4cbbb2011-02-06 11:19:1010728 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3010729 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4110730 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3010731 if (rv == ERR_IO_PENDING)
10732 rv = callback.WaitForResult();
10733 EXPECT_EQ(OK, rv);
10734 response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5010735 ASSERT_TRUE(response != NULL);
[email protected]eca50e122010-09-11 14:03:3010736 EXPECT_TRUE(response->auth_challenge.get() == NULL);
[email protected]ab739042011-04-07 15:22:2810737 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010738
10739 // Read the body since the fourth round was successful. This will also
10740 // release the socket back to the pool.
10741 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5010742 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010743 if (rv == ERR_IO_PENDING)
10744 rv = callback.WaitForResult();
10745 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010746 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010747 EXPECT_EQ(0, rv);
10748 // There are still 0 idle sockets, since the trans_compete transaction
10749 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2810750 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1010751
10752 // The competing request can now finish. Wait for the headers and then
10753 // read the body.
10754 rv = callback_compete.WaitForResult();
10755 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5010756 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010757 if (rv == ERR_IO_PENDING)
10758 rv = callback.WaitForResult();
10759 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5010760 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1010761 EXPECT_EQ(0, rv);
10762
10763 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2810764 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1410765}
10766
[email protected]65041fa2010-05-21 06:56:5310767// This tests the case that a request is issued via http instead of spdy after
10768// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0210769TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
bnc55ff9da2015-08-19 18:42:3510770 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310771 NextProtoVector next_protos;
[email protected]0ce3af82013-07-22 16:17:1610772 next_protos.push_back(kProtoHTTP11);
[email protected]d7599122014-05-24 03:37:2310773 session_deps_.next_protos = next_protos;
10774
[email protected]65041fa2010-05-21 06:56:5310775 HttpRequestInfo request;
10776 request.method = "GET";
bncce36dca22015-04-21 22:11:2310777 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5310778 request.load_flags = 0;
10779
10780 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310781 MockWrite(
10782 "GET / HTTP/1.1\r\n"
10783 "Host: www.example.org\r\n"
10784 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5310785 };
10786
[email protected]8a0fc822013-06-27 20:52:4310787 std::string alternate_protocol_http_header =
10788 GetAlternateProtocolHttpHeader();
10789
[email protected]65041fa2010-05-21 06:56:5310790 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210791 MockRead("HTTP/1.1 200 OK\r\n"),
10792 MockRead(alternate_protocol_http_header.c_str()),
10793 MockRead("\r\n"),
10794 MockRead("hello world"),
10795 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5310796 };
10797
[email protected]8ddf8322012-02-23 18:08:0610798 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4810799 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5310800
[email protected]bb88e1d32013-05-03 23:11:0710801 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5310802
10803 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
10804 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0710805 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5310806
[email protected]49639fa2011-12-20 23:22:4110807 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5310808
[email protected]bb88e1d32013-05-03 23:11:0710809 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610810 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010811 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5310812
[email protected]49639fa2011-12-20 23:22:4110813 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5310814
10815 EXPECT_EQ(ERR_IO_PENDING, rv);
10816 EXPECT_EQ(OK, callback.WaitForResult());
10817
10818 const HttpResponseInfo* response = trans->GetResponseInfo();
10819 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5010820 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]65041fa2010-05-21 06:56:5310821 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10822
10823 std::string response_data;
10824 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10825 EXPECT_EQ("hello world", response_data);
10826
10827 EXPECT_FALSE(response->was_fetched_via_spdy);
10828 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5310829}
[email protected]26ef6582010-06-24 02:30:4710830
bnc55ff9da2015-08-19 18:42:3510831// Simulate the SSL handshake completing with an NPN negotiation followed by an
10832// immediate server closing of the socket.
10833// Regression test for https://crbug.com/46369.
[email protected]23e482282013-06-14 16:08:0210834TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
bnc55ff9da2015-08-19 18:42:3510835 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310836 session_deps_.next_protos = SpdyNextProtos();
[email protected]26ef6582010-06-24 02:30:4710837
10838 HttpRequestInfo request;
10839 request.method = "GET";
bncce36dca22015-04-21 22:11:2310840 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4710841 request.load_flags = 0;
10842
[email protected]8ddf8322012-02-23 18:08:0610843 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0210844 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0710845 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4710846
[email protected]cdf8f7e72013-05-23 10:56:4610847 scoped_ptr<SpdyFrame> req(
10848 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310849 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4710850
10851 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0610852 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4710853 };
10854
rch8e6c6c42015-05-01 14:05:1310855 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10856 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710857 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4710858
[email protected]49639fa2011-12-20 23:22:4110859 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4710860
[email protected]bb88e1d32013-05-03 23:11:0710861 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3610862 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010863 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4710864
[email protected]49639fa2011-12-20 23:22:4110865 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4710866 EXPECT_EQ(ERR_IO_PENDING, rv);
10867 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4710868}
[email protected]65d34382010-07-01 18:12:2610869
[email protected]795cbf82013-07-22 09:37:2710870// A subclass of HttpAuthHandlerMock that records the request URL when
10871// it gets it. This is needed since the auth handler may get destroyed
10872// before we get a chance to query it.
10873class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
10874 public:
10875 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
10876
dchengb03027d2014-10-21 12:00:2010877 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2710878
10879 protected:
dchengb03027d2014-10-21 12:00:2010880 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
10881 const HttpRequestInfo* request,
10882 const CompletionCallback& callback,
10883 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2710884 *url_ = request->url;
10885 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
10886 credentials, request, callback, auth_token);
10887 }
10888
10889 private:
10890 GURL* url_;
10891};
10892
bnc55ff9da2015-08-19 18:42:3510893// This test ensures that the URL passed into the proxy is upgraded to https
10894// when doing an Alternate Protocol upgrade.
[email protected]23e482282013-06-14 16:08:0210895TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
bnc55ff9da2015-08-19 18:42:3510896 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2310897 session_deps_.next_protos = SpdyNextProtos();
[email protected]f45c1ee2010-08-03 00:54:3010898
[email protected]bb88e1d32013-05-03 23:11:0710899 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2010900 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5110901 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710902 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2710903 GURL request_url;
10904 {
10905 HttpAuthHandlerMock::Factory* auth_factory =
10906 new HttpAuthHandlerMock::Factory();
10907 UrlRecordingHttpAuthHandlerMock* auth_handler =
10908 new UrlRecordingHttpAuthHandlerMock(&request_url);
10909 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
10910 auth_factory->set_do_init_from_challenge(true);
10911 session_deps_.http_auth_handler_factory.reset(auth_factory);
10912 }
[email protected]f45c1ee2010-08-03 00:54:3010913
10914 HttpRequestInfo request;
10915 request.method = "GET";
bncce36dca22015-04-21 22:11:2310916 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3010917 request.load_flags = 0;
10918
10919 // First round goes unauthenticated through the proxy.
10920 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2310921 MockWrite(
10922 "GET http://www.example.org/ HTTP/1.1\r\n"
10923 "Host: www.example.org\r\n"
10924 "Proxy-Connection: keep-alive\r\n"
10925 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010926 };
10927 MockRead data_reads_1[] = {
[email protected]8ddf8322012-02-23 18:08:0610928 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
bnc33b8cef42014-11-19 17:30:3810929 MockRead("HTTP/1.1 200 OK\r\n"),
10930 MockRead("Alternate-Protocol: 443:"),
10931 MockRead(GetAlternateProtocolFromParam()),
10932 MockRead("\r\n"),
10933 MockRead("Proxy-Connection: close\r\n"),
10934 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010935 };
10936 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
10937 data_writes_1, arraysize(data_writes_1));
10938
bncce36dca22015-04-21 22:11:2310939 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3010940 // Alternate-Protocol announcement in the first round. It fails due
10941 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2310942 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5910943 // Proxy-Authorization headers. There is then a SPDY request round.
10944 //
[email protected]fe3b7dc2012-02-03 19:52:0910945 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
10946 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
10947 // does a Disconnect and Connect on the same socket, rather than trying
10948 // to obtain a new one.
10949 //
[email protected]394816e92010-08-03 07:38:5910950 // NOTE: Originally, the proxy response to the second CONNECT request
10951 // simply returned another 407 so the unit test could skip the SSL connection
10952 // establishment and SPDY framing issues. Alas, the
10953 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3010954 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5910955
[email protected]cdf8f7e72013-05-23 10:56:4610956 scoped_ptr<SpdyFrame> req(
10957 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
[email protected]23e482282013-06-14 16:08:0210958 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
10959 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3010960
[email protected]394816e92010-08-03 07:38:5910961 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2310962 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1310963 MockWrite(ASYNC, 0,
10964 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10965 "Host: www.example.org\r\n"
10966 "Proxy-Connection: keep-alive\r\n"
10967 "\r\n"),
[email protected]394816e92010-08-03 07:38:5910968
bncce36dca22015-04-21 22:11:2310969 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1310970 MockWrite(ASYNC, 2,
10971 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10972 "Host: www.example.org\r\n"
10973 "Proxy-Connection: keep-alive\r\n"
10974 "Proxy-Authorization: auth_token\r\n"
10975 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3010976
bncce36dca22015-04-21 22:11:2310977 // SPDY request
rch8e6c6c42015-05-01 14:05:1310978 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3010979 };
[email protected]394816e92010-08-03 07:38:5910980 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1310981 // First connection attempt fails
mmenkee0b5c882015-08-26 20:29:1110982 MockRead(ASYNC, 1,
10983 "HTTP/1.1 407 Unauthorized\r\n"
10984 "Proxy-Authenticate: Mock\r\n"
10985 "Content-Length: 0\r\n"
10986 "Proxy-Connection: keep-alive\r\n"
10987 "\r\n"),
[email protected]394816e92010-08-03 07:38:5910988
rch8e6c6c42015-05-01 14:05:1310989 // Second connection attempt passes
mmenkee0b5c882015-08-26 20:29:1110990 MockRead(ASYNC, 3, "HTTP/1.1 200 Connected\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:5910991
rch8e6c6c42015-05-01 14:05:1310992 // SPDY response
mmenkee0b5c882015-08-26 20:29:1110993 CreateMockRead(*resp.get(), 5), CreateMockRead(*data.get(), 6),
rch8e6c6c42015-05-01 14:05:1310994 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5910995 };
rch8e6c6c42015-05-01 14:05:1310996 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
10997 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3010998
[email protected]8ddf8322012-02-23 18:08:0610999 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211000 ssl.SetNextProto(GetParam());
bncce36dca22015-04-21 22:11:2311001 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
11002 ASSERT_TRUE(ssl.cert.get());
[email protected]f45c1ee2010-08-03 00:54:3011003
[email protected]d973e99a2012-02-17 21:02:3611004 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511005 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11006 NULL, 0, NULL, 0);
11007 hanging_non_alternate_protocol_socket.set_connect_data(
11008 never_finishing_connect);
11009
[email protected]bb88e1d32013-05-03 23:11:0711010 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
11011 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
11012 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11013 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511014 &hanging_non_alternate_protocol_socket);
[email protected]bb88e1d32013-05-03 23:11:0711015 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3011016
11017 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4111018 TestCompletionCallback callback_1;
[email protected]262eec82013-03-19 21:01:3611019 scoped_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5011020 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111021 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3011022 EXPECT_EQ(ERR_IO_PENDING, rv);
11023 EXPECT_EQ(OK, callback_1.WaitForResult());
11024
11025 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4111026 TestCompletionCallback callback_2;
[email protected]262eec82013-03-19 21:01:3611027 scoped_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5011028 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111029 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3011030 EXPECT_EQ(ERR_IO_PENDING, rv);
11031 EXPECT_EQ(OK, callback_2.WaitForResult());
11032 const HttpResponseInfo* response = trans_2->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011033 ASSERT_TRUE(response != NULL);
[email protected]f45c1ee2010-08-03 00:54:3011034 ASSERT_FALSE(response->auth_challenge.get() == NULL);
11035
11036 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4111037 TestCompletionCallback callback_3;
11038 rv = trans_2->RestartWithAuth(
11039 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3011040 EXPECT_EQ(ERR_IO_PENDING, rv);
11041 EXPECT_EQ(OK, callback_3.WaitForResult());
11042
11043 // After all that work, these two lines (or actually, just the scheme) are
11044 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3011045 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2311046 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3011047
[email protected]029c83b62013-01-24 05:28:2011048 LoadTimingInfo load_timing_info;
11049 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
11050 TestLoadTimingNotReusedWithPac(load_timing_info,
11051 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3811052}
11053
11054// Test that if we cancel the transaction as the connection is completing, that
11055// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0211056TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3811057 // Setup everything about the connection to complete synchronously, so that
11058 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
11059 // for is the callback from the HttpStreamRequest.
11060 // Then cancel the transaction.
11061 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3611062 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3811063 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0611064 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
11065 MockRead(SYNCHRONOUS, "hello world"),
11066 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3811067 };
11068
[email protected]8e6441ca2010-08-19 05:56:3811069 HttpRequestInfo request;
11070 request.method = "GET";
bncce36dca22015-04-21 22:11:2311071 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3811072 request.load_flags = 0;
11073
[email protected]bb88e1d32013-05-03 23:11:0711074 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]3fe8d2f82013-10-17 08:56:0711075 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:2711076 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4111077 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2711078
[email protected]8e6441ca2010-08-19 05:56:3811079 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11080 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711081 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3811082
[email protected]49639fa2011-12-20 23:22:4111083 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3811084
vishal.b62985ca92015-04-17 08:45:5111085 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4111086 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3811087 EXPECT_EQ(ERR_IO_PENDING, rv);
11088 trans.reset(); // Cancel the transaction here.
11089
[email protected]2da659e2013-05-23 20:51:3411090 base::MessageLoop::current()->RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3011091}
11092
[email protected]ecab6e052014-05-16 14:58:1211093// Test that if a transaction is cancelled after receiving the headers, the
11094// stream is drained properly and added back to the socket pool. The main
11095// purpose of this test is to make sure that an HttpStreamParser can be read
11096// from after the HttpNetworkTransaction and the objects it owns have been
11097// deleted.
11098// See http://crbug.com/368418
11099TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
11100 MockRead data_reads[] = {
11101 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
11102 MockRead(ASYNC, "Content-Length: 2\r\n"),
11103 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
11104 MockRead(ASYNC, "1"),
11105 // 2 async reads are necessary to trigger a ReadResponseBody call after the
11106 // HttpNetworkTransaction has been deleted.
11107 MockRead(ASYNC, "2"),
11108 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
11109 };
11110 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
11111 session_deps_.socket_factory->AddSocketDataProvider(&data);
11112
11113 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11114
11115 {
11116 HttpRequestInfo request;
11117 request.method = "GET";
bncce36dca22015-04-21 22:11:2311118 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1211119 request.load_flags = 0;
11120
dcheng48459ac22014-08-26 00:46:4111121 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1211122 TestCompletionCallback callback;
11123
11124 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
11125 EXPECT_EQ(ERR_IO_PENDING, rv);
11126 callback.WaitForResult();
11127
11128 const HttpResponseInfo* response = trans.GetResponseInfo();
11129 ASSERT_TRUE(response != NULL);
11130 EXPECT_TRUE(response->headers.get() != NULL);
11131 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11132
11133 // The transaction and HttpRequestInfo are deleted.
11134 }
11135
11136 // Let the HttpResponseBodyDrainer drain the socket.
11137 base::MessageLoop::current()->RunUntilIdle();
11138
11139 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4111140 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1211141}
11142
[email protected]76a505b2010-08-25 06:23:0011143// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0211144TEST_P(HttpNetworkTransactionTest, ProxyGet) {
[email protected]bb88e1d32013-05-03 23:11:0711145 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2011146 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5111147 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711148 session_deps_.net_log = log.bound().net_log();
11149 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011150
[email protected]76a505b2010-08-25 06:23:0011151 HttpRequestInfo request;
11152 request.method = "GET";
bncce36dca22015-04-21 22:11:2311153 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011154
11155 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311156 MockWrite(
11157 "GET http://www.example.org/ HTTP/1.1\r\n"
11158 "Host: www.example.org\r\n"
11159 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011160 };
11161
11162 MockRead data_reads1[] = {
11163 MockRead("HTTP/1.1 200 OK\r\n"),
11164 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11165 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611166 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0011167 };
11168
11169 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11170 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711171 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0011172
[email protected]49639fa2011-12-20 23:22:4111173 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011174
[email protected]262eec82013-03-19 21:01:3611175 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011176 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]597a1ab2014-06-26 08:12:2711177 BeforeProxyHeadersSentHandler proxy_headers_handler;
11178 trans->SetBeforeProxyHeadersSentCallback(
11179 base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
11180 base::Unretained(&proxy_headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5011181
[email protected]49639fa2011-12-20 23:22:4111182 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011183 EXPECT_EQ(ERR_IO_PENDING, rv);
11184
11185 rv = callback1.WaitForResult();
11186 EXPECT_EQ(OK, rv);
11187
11188 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011189 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0011190
11191 EXPECT_TRUE(response->headers->IsKeepAlive());
11192 EXPECT_EQ(200, response->headers->response_code());
11193 EXPECT_EQ(100, response->headers->GetContentLength());
11194 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1511195 EXPECT_TRUE(
11196 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]597a1ab2014-06-26 08:12:2711197 EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
11198 EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0011199 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2011200
11201 LoadTimingInfo load_timing_info;
11202 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11203 TestLoadTimingNotReusedWithPac(load_timing_info,
11204 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0011205}
11206
11207// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0211208TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
[email protected]bb88e1d32013-05-03 23:11:0711209 session_deps_.proxy_service.reset(
[email protected]029c83b62013-01-24 05:28:2011210 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5111211 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711212 session_deps_.net_log = log.bound().net_log();
11213 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011214
[email protected]76a505b2010-08-25 06:23:0011215 HttpRequestInfo request;
11216 request.method = "GET";
bncce36dca22015-04-21 22:11:2311217 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011218
11219 // Since we have proxy, should try to establish tunnel.
11220 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311221 MockWrite(
11222 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11223 "Host: www.example.org\r\n"
11224 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011225
bncce36dca22015-04-21 22:11:2311226 MockWrite(
11227 "GET / HTTP/1.1\r\n"
11228 "Host: www.example.org\r\n"
11229 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011230 };
11231
11232 MockRead data_reads1[] = {
11233 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
11234
11235 MockRead("HTTP/1.1 200 OK\r\n"),
11236 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11237 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611238 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0011239 };
11240
11241 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11242 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711243 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0611244 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711245 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0011246
[email protected]49639fa2011-12-20 23:22:4111247 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011248
[email protected]262eec82013-03-19 21:01:3611249 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011250 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5011251
[email protected]49639fa2011-12-20 23:22:4111252 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011253 EXPECT_EQ(ERR_IO_PENDING, rv);
11254
11255 rv = callback1.WaitForResult();
11256 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4611257 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4011258 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0011259 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011260 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0011261 NetLog::PHASE_NONE);
11262 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011263 entries, pos,
[email protected]76a505b2010-08-25 06:23:0011264 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
11265 NetLog::PHASE_NONE);
11266
11267 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:5011268 ASSERT_TRUE(response != NULL);
[email protected]76a505b2010-08-25 06:23:0011269
11270 EXPECT_TRUE(response->headers->IsKeepAlive());
11271 EXPECT_EQ(200, response->headers->response_code());
11272 EXPECT_EQ(100, response->headers->GetContentLength());
11273 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
11274 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1511275 EXPECT_TRUE(
11276 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
[email protected]029c83b62013-01-24 05:28:2011277
11278 LoadTimingInfo load_timing_info;
11279 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11280 TestLoadTimingNotReusedWithPac(load_timing_info,
11281 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0011282}
11283
11284// Test a basic HTTPS GET request through a proxy, but the server hangs up
11285// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0211286TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
[email protected]bb88e1d32013-05-03 23:11:0711287 session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
vishal.b62985ca92015-04-17 08:45:5111288 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711289 session_deps_.net_log = log.bound().net_log();
11290 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0011291
[email protected]76a505b2010-08-25 06:23:0011292 HttpRequestInfo request;
11293 request.method = "GET";
bncce36dca22015-04-21 22:11:2311294 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0011295
11296 // Since we have proxy, should try to establish tunnel.
11297 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311298 MockWrite(
11299 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11300 "Host: www.example.org\r\n"
11301 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011302
bncce36dca22015-04-21 22:11:2311303 MockWrite(
11304 "GET / HTTP/1.1\r\n"
11305 "Host: www.example.org\r\n"
11306 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0011307 };
11308
11309 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0611310 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0011311 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611312 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0011313 };
11314
11315 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
11316 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0711317 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0611318 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711319 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0011320
[email protected]49639fa2011-12-20 23:22:4111321 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0011322
[email protected]262eec82013-03-19 21:01:3611323 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011324 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5011325
[email protected]49639fa2011-12-20 23:22:4111326 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0011327 EXPECT_EQ(ERR_IO_PENDING, rv);
11328
11329 rv = callback1.WaitForResult();
11330 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4611331 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4011332 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0011333 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011334 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0011335 NetLog::PHASE_NONE);
11336 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4011337 entries, pos,
[email protected]76a505b2010-08-25 06:23:0011338 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
11339 NetLog::PHASE_NONE);
11340}
11341
[email protected]749eefa82010-09-13 22:14:0311342// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0211343TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
[email protected]cdf8f7e72013-05-23 10:56:4611344 scoped_ptr<SpdyFrame> req(
bncce36dca22015-04-21 22:11:2311345 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1311346 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0311347
[email protected]23e482282013-06-14 16:08:0211348 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11349 scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0311350 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311351 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0311352 };
11353
rch8e6c6c42015-05-01 14:05:1311354 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11355 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711356 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0311357
[email protected]8ddf8322012-02-23 18:08:0611358 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211359 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711360 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0311361
[email protected]bb88e1d32013-05-03 23:11:0711362 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0311363
11364 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2311365 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011366 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311367 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711368 base::WeakPtr<SpdySession> spdy_session =
[email protected]41d64e82013-07-03 22:44:2611369 CreateInsecureSpdySession(session, key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0311370
11371 HttpRequestInfo request;
11372 request.method = "GET";
bncce36dca22015-04-21 22:11:2311373 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0311374 request.load_flags = 0;
11375
11376 // This is the important line that marks this as a preconnect.
11377 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
11378
[email protected]262eec82013-03-19 21:01:3611379 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011380 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0311381
[email protected]41d64e82013-07-03 22:44:2611382 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4111383 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0311384 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111385 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0311386}
11387
[email protected]73b8dd222010-11-11 19:55:2411388// Given a net error, cause that error to be returned from the first Write()
11389// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0211390void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0711391 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2911392 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711393 request_info.url = GURL("https://www.example.com/");
11394 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911395 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711396
[email protected]8ddf8322012-02-23 18:08:0611397 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2911398 MockWrite data_writes[] = {
11399 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2411400 };
ttuttle859dc7a2015-04-23 19:42:2911401 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0711402 session_deps_.socket_factory->AddSocketDataProvider(&data);
11403 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2411404
[email protected]bb88e1d32013-05-03 23:11:0711405 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611406 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011407 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2411408
[email protected]49639fa2011-12-20 23:22:4111409 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911410 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11411 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2411412 rv = callback.WaitForResult();
11413 ASSERT_EQ(error, rv);
11414}
11415
[email protected]23e482282013-06-14 16:08:0211416TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2411417 // Just check a grab bag of cert errors.
11418 static const int kErrors[] = {
11419 ERR_CERT_COMMON_NAME_INVALID,
11420 ERR_CERT_AUTHORITY_INVALID,
11421 ERR_CERT_DATE_INVALID,
11422 };
11423 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0611424 CheckErrorIsPassedBack(kErrors[i], ASYNC);
11425 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2411426 }
11427}
11428
[email protected]bd0b6772011-01-11 19:59:3011429// Ensure that a client certificate is removed from the SSL client auth
11430// cache when:
11431// 1) No proxy is involved.
11432// 2) TLS False Start is disabled.
11433// 3) The initial TLS handshake requests a client certificate.
11434// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211435TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311436 ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911437 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711438 request_info.url = GURL("https://www.example.com/");
11439 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911440 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711441
[email protected]bd0b6772011-01-11 19:59:3011442 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111443 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011444
11445 // [ssl_]data1 contains the data for the first SSL handshake. When a
11446 // CertificateRequest is received for the first time, the handshake will
11447 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2911448 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011449 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711450 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911451 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711452 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011453
11454 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
11455 // False Start is not being used, the result of the SSL handshake will be
11456 // returned as part of the SSLClientSocket::Connect() call. This test
11457 // matches the result of a server sending a handshake_failure alert,
11458 // rather than a Finished message, because it requires a client
11459 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2911460 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011461 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711462 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911463 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711464 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011465
11466 // [ssl_]data3 contains the data for the third SSL handshake. When a
11467 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211468 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
11469 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3011470 // of the HttpNetworkTransaction. Because this test failure is due to
11471 // requiring a client certificate, this fallback handshake should also
11472 // fail.
ttuttle859dc7a2015-04-23 19:42:2911473 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3011474 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711475 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911476 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711477 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011478
[email protected]80c75f682012-05-26 16:22:1711479 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
11480 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4211481 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
11482 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1711483 // of the HttpNetworkTransaction. Because this test failure is due to
11484 // requiring a client certificate, this fallback handshake should also
11485 // fail.
ttuttle859dc7a2015-04-23 19:42:2911486 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1711487 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711488 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911489 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711490 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711491
[email protected]bb88e1d32013-05-03 23:11:0711492 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611493 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011494 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011495
[email protected]bd0b6772011-01-11 19:59:3011496 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4111497 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911498 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11499 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011500
11501 // Complete the SSL handshake, which should abort due to requiring a
11502 // client certificate.
11503 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911504 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011505
11506 // Indicate that no certificate should be supplied. From the perspective
11507 // of SSLClientCertCache, NULL is just as meaningful as a real
11508 // certificate, so this is the same as supply a
11509 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111510 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911511 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011512
11513 // Ensure the certificate was added to the client auth cache before
11514 // allowing the connection to continue restarting.
11515 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111516 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11517 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011518 ASSERT_EQ(NULL, client_cert.get());
11519
11520 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711521 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11522 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011523 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911524 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011525
11526 // Ensure that the client certificate is removed from the cache on a
11527 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111528 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11529 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011530}
11531
11532// Ensure that a client certificate is removed from the SSL client auth
11533// cache when:
11534// 1) No proxy is involved.
11535// 2) TLS False Start is enabled.
11536// 3) The initial TLS handshake requests a client certificate.
11537// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0211538TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2311539 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2911540 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2711541 request_info.url = GURL("https://www.example.com/");
11542 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911543 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2711544
[email protected]bd0b6772011-01-11 19:59:3011545 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111546 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3011547
11548 // When TLS False Start is used, SSLClientSocket::Connect() calls will
11549 // return successfully after reading up to the peer's Certificate message.
11550 // This is to allow the caller to call SSLClientSocket::Write(), which can
11551 // enqueue application data to be sent in the same packet as the
11552 // ChangeCipherSpec and Finished messages.
11553 // The actual handshake will be finished when SSLClientSocket::Read() is
11554 // called, which expects to process the peer's ChangeCipherSpec and
11555 // Finished messages. If there was an error negotiating with the peer,
11556 // such as due to the peer requiring a client certificate when none was
11557 // supplied, the alert sent by the peer won't be processed until Read() is
11558 // called.
11559
11560 // Like the non-False Start case, when a client certificate is requested by
11561 // the peer, the handshake is aborted during the Connect() call.
11562 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2911563 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3011564 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711565 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911566 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711567 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3011568
11569 // When a client certificate is supplied, Connect() will not be aborted
11570 // when the peer requests the certificate. Instead, the handshake will
11571 // artificially succeed, allowing the caller to write the HTTP request to
11572 // the socket. The handshake messages are not processed until Read() is
11573 // called, which then detects that the handshake was aborted, due to the
11574 // peer sending a handshake_failure because it requires a client
11575 // certificate.
ttuttle859dc7a2015-04-23 19:42:2911576 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011577 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711578 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911579 MockRead data2_reads[] = {
11580 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3011581 };
ttuttle859dc7a2015-04-23 19:42:2911582 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711583 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3011584
11585 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1711586 // the data for the SSL handshake once the TLSv1.1 connection falls back to
11587 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911588 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3011589 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711590 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911591 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711592 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3011593
[email protected]80c75f682012-05-26 16:22:1711594 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
11595 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2911596 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1711597 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711598 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2911599 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711600 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1711601
[email protected]7799de12013-05-30 05:52:5111602 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2911603 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5111604 ssl_data5.cert_request_info = cert_request.get();
11605 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2911606 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5111607 session_deps_.socket_factory->AddSocketDataProvider(&data5);
11608
[email protected]bb88e1d32013-05-03 23:11:0711609 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]262eec82013-03-19 21:01:3611610 scoped_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011611 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3011612
[email protected]bd0b6772011-01-11 19:59:3011613 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4111614 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911615 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
11616 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011617
11618 // Complete the SSL handshake, which should abort due to requiring a
11619 // client certificate.
11620 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911621 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3011622
11623 // Indicate that no certificate should be supplied. From the perspective
11624 // of SSLClientCertCache, NULL is just as meaningful as a real
11625 // certificate, so this is the same as supply a
11626 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111627 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911628 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3011629
11630 // Ensure the certificate was added to the client auth cache before
11631 // allowing the connection to continue restarting.
11632 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111633 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11634 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011635 ASSERT_EQ(NULL, client_cert.get());
11636
[email protected]bd0b6772011-01-11 19:59:3011637 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1711638 // then consume ssl_data3 and ssl_data4, both of which should also fail.
11639 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3011640 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911641 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3011642
11643 // Ensure that the client certificate is removed from the cache on a
11644 // handshake failure.
[email protected]791879c2013-12-17 07:22:4111645 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11646 HostPortPair("www.example.com", 443), &client_cert));
[email protected]bd0b6772011-01-11 19:59:3011647}
11648
[email protected]8c405132011-01-11 22:03:1811649// Ensure that a client certificate is removed from the SSL client auth
11650// cache when:
11651// 1) An HTTPS proxy is involved.
11652// 3) The HTTPS proxy requests a client certificate.
11653// 4) The client supplies an invalid/unacceptable certificate for the
11654// proxy.
11655// The test is repeated twice, first for connecting to an HTTPS endpoint,
11656// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0211657TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
[email protected]bb88e1d32013-05-03 23:11:0711658 session_deps_.proxy_service.reset(
[email protected]8c405132011-01-11 22:03:1811659 ProxyService::CreateFixed("https://proxy:70"));
vishal.b62985ca92015-04-17 08:45:5111660 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0711661 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1811662
11663 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4111664 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1811665
11666 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
11667 // [ssl_]data[1-3]. Rather than represending the endpoint
11668 // (www.example.com:443), they represent failures with the HTTPS proxy
11669 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2911670 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1811671 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711672 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2911673 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711674 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1811675
ttuttle859dc7a2015-04-23 19:42:2911676 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811677 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711678 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2911679 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711680 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1811681
[email protected]80c75f682012-05-26 16:22:1711682 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
11683#if 0
ttuttle859dc7a2015-04-23 19:42:2911684 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1811685 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0711686 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2911687 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711688 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1711689#endif
[email protected]8c405132011-01-11 22:03:1811690
ttuttle859dc7a2015-04-23 19:42:2911691 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1811692 requests[0].url = GURL("https://www.example.com/");
11693 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911694 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811695
11696 requests[1].url = GURL("http://www.example.com/");
11697 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2911698 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1811699
11700 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0711701 session_deps_.socket_factory->ResetNextMockIndexes();
11702 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c405132011-01-11 22:03:1811703 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5011704 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1811705
11706 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4111707 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2911708 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
11709 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811710
11711 // Complete the SSL handshake, which should abort due to requiring a
11712 // client certificate.
11713 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911714 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1811715
11716 // Indicate that no certificate should be supplied. From the perspective
11717 // of SSLClientCertCache, NULL is just as meaningful as a real
11718 // certificate, so this is the same as supply a
11719 // legitimate-but-unacceptable certificate.
[email protected]49639fa2011-12-20 23:22:4111720 rv = trans->RestartWithCertificate(NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2911721 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1811722
11723 // Ensure the certificate was added to the client auth cache before
11724 // allowing the connection to continue restarting.
11725 scoped_refptr<X509Certificate> client_cert;
[email protected]791879c2013-12-17 07:22:4111726 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
11727 HostPortPair("proxy", 70), &client_cert));
[email protected]8c405132011-01-11 22:03:1811728 ASSERT_EQ(NULL, client_cert.get());
11729 // Ensure the certificate was NOT cached for the endpoint. This only
11730 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4111731 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11732 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811733
11734 // Restart the handshake. This will consume ssl_data2, which fails, and
11735 // then consume ssl_data3, which should also fail. The result code is
11736 // checked against what ssl_data3 should return.
11737 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2911738 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1811739
11740 // Now that the new handshake has failed, ensure that the client
11741 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4111742 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11743 HostPortPair("proxy", 70), &client_cert));
11744 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
11745 HostPortPair("www.example.com", 443), &client_cert));
[email protected]8c405132011-01-11 22:03:1811746 }
11747}
11748
mmenke5c642132015-06-02 16:05:1311749TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
bnc55ff9da2015-08-19 18:42:3511750 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311751 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611752
11753 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711754 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11755 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611756 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11757 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611758
[email protected]8ddf8322012-02-23 18:08:0611759 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211760 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711761 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611762
[email protected]cdf8f7e72013-05-23 10:56:4611763 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311764 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611765 scoped_ptr<SpdyFrame> host2_req(
11766 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611767 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311768 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611769 };
[email protected]23e482282013-06-14 16:08:0211770 scoped_ptr<SpdyFrame> host1_resp(
11771 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11772 scoped_ptr<SpdyFrame> host1_resp_body(
11773 spdy_util_.ConstructSpdyBodyFrame(1, true));
11774 scoped_ptr<SpdyFrame> host2_resp(
11775 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11776 scoped_ptr<SpdyFrame> host2_resp_body(
11777 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4611778 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311779 CreateMockRead(*host1_resp, 1),
11780 CreateMockRead(*host1_resp_body, 2),
11781 CreateMockRead(*host2_resp, 4),
11782 CreateMockRead(*host2_resp_body, 5),
11783 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4611784 };
11785
[email protected]d2b5f092012-06-08 23:55:0211786 IPAddressNumber ip;
11787 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11788 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11789 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311790 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11791 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711792 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4611793
[email protected]aa22b242011-11-16 18:58:2911794 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4611795 HttpRequestInfo request1;
11796 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311797 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4611798 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011799 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611800
[email protected]49639fa2011-12-20 23:22:4111801 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611802 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111803 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611804
11805 const HttpResponseInfo* response = trans1.GetResponseInfo();
11806 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011807 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611808 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11809
11810 std::string response_data;
11811 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11812 EXPECT_EQ("hello!", response_data);
11813
11814 // Preload www.gmail.com into HostCache.
11815 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1011816 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4611817 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1011818 rv = session_deps_.host_resolver->Resolve(resolve_info,
11819 DEFAULT_PRIORITY,
11820 &ignored,
11821 callback.callback(),
11822 NULL,
11823 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4711824 EXPECT_EQ(ERR_IO_PENDING, rv);
11825 rv = callback.WaitForResult();
11826 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4611827
11828 HttpRequestInfo request2;
11829 request2.method = "GET";
11830 request2.url = GURL("https://www.gmail.com/");
11831 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011832 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4611833
[email protected]49639fa2011-12-20 23:22:4111834 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4611835 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111836 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4611837
11838 response = trans2.GetResponseInfo();
11839 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011840 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4611841 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11842 EXPECT_TRUE(response->was_fetched_via_spdy);
11843 EXPECT_TRUE(response->was_npn_negotiated);
11844 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11845 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4611846}
11847
[email protected]23e482282013-06-14 16:08:0211848TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
bnc55ff9da2015-08-19 18:42:3511849 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311850 session_deps_.next_protos = SpdyNextProtos();
[email protected]d2b5f092012-06-08 23:55:0211851
11852 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0711853 session_deps_.host_resolver.reset(new MockCachingHostResolver());
11854 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0211855 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11856 pool_peer.DisableDomainAuthenticationVerification();
11857
11858 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211859 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711860 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0211861
[email protected]cdf8f7e72013-05-23 10:56:4611862 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311863 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611864 scoped_ptr<SpdyFrame> host2_req(
11865 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0211866 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311867 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0211868 };
[email protected]23e482282013-06-14 16:08:0211869 scoped_ptr<SpdyFrame> host1_resp(
11870 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
11871 scoped_ptr<SpdyFrame> host1_resp_body(
11872 spdy_util_.ConstructSpdyBodyFrame(1, true));
11873 scoped_ptr<SpdyFrame> host2_resp(
11874 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
11875 scoped_ptr<SpdyFrame> host2_resp_body(
11876 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0211877 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311878 CreateMockRead(*host1_resp, 1),
11879 CreateMockRead(*host1_resp_body, 2),
11880 CreateMockRead(*host2_resp, 4),
11881 CreateMockRead(*host2_resp_body, 5),
11882 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0211883 };
11884
11885 IPAddressNumber ip;
11886 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
11887 IPEndPoint peer_addr = IPEndPoint(ip, 443);
11888 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1311889 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
11890 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711891 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0211892
11893 TestCompletionCallback callback;
11894 HttpRequestInfo request1;
11895 request1.method = "GET";
bncce36dca22015-04-21 22:11:2311896 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0211897 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011898 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211899
11900 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
11901 EXPECT_EQ(ERR_IO_PENDING, rv);
11902 EXPECT_EQ(OK, callback.WaitForResult());
11903
11904 const HttpResponseInfo* response = trans1.GetResponseInfo();
11905 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011906 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211907 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11908
11909 std::string response_data;
11910 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11911 EXPECT_EQ("hello!", response_data);
11912
11913 HttpRequestInfo request2;
11914 request2.method = "GET";
11915 request2.url = GURL("https://www.gmail.com/");
11916 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5011917 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0211918
11919 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
11920 EXPECT_EQ(ERR_IO_PENDING, rv);
11921 EXPECT_EQ(OK, callback.WaitForResult());
11922
11923 response = trans2.GetResponseInfo();
11924 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5011925 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]d2b5f092012-06-08 23:55:0211926 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11927 EXPECT_TRUE(response->was_fetched_via_spdy);
11928 EXPECT_TRUE(response->was_npn_negotiated);
11929 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11930 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0211931}
11932
ttuttle859dc7a2015-04-23 19:42:2911933class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4611934 public:
11935 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
11936 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2011937 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4611938
11939 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
11940
11941 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2011942 int Resolve(const RequestInfo& info,
11943 RequestPriority priority,
11944 AddressList* addresses,
11945 const CompletionCallback& callback,
11946 RequestHandle* out_req,
11947 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011948 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1011949 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4011950 }
11951
dchengb03027d2014-10-21 12:00:2011952 int ResolveFromCache(const RequestInfo& info,
11953 AddressList* addresses,
11954 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4011955 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
11956 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0911957 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4611958 return rv;
11959 }
11960
dchengb03027d2014-10-21 12:00:2011961 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4611962 host_resolver_.CancelRequest(req);
11963 }
11964
[email protected]46da33be2011-07-19 21:58:0411965 MockCachingHostResolver* GetMockHostResolver() {
11966 return &host_resolver_;
11967 }
11968
[email protected]e3ceb682011-06-28 23:55:4611969 private:
11970 MockCachingHostResolver host_resolver_;
11971 const HostPortPair host_port_;
11972};
11973
mmenke5c642132015-06-02 16:05:1311974TEST_P(HttpNetworkTransactionTest,
11975 UseIPConnectionPoolingWithHostCacheExpiration) {
bnc55ff9da2015-08-19 18:42:3511976 session_deps_.use_alternative_services = true;
[email protected]d7599122014-05-24 03:37:2311977 session_deps_.next_protos = SpdyNextProtos();
[email protected]e3ceb682011-06-28 23:55:4611978
11979 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4611980 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3411981 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0711982 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4611983 params.host_resolver = &host_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711984 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2611985 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
11986 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4611987
[email protected]8ddf8322012-02-23 18:08:0611988 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0211989 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0711990 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4611991
[email protected]cdf8f7e72013-05-23 10:56:4611992 scoped_ptr<SpdyFrame> host1_req(
bncce36dca22015-04-21 22:11:2311993 spdy_util_.ConstructSpdyGet("https://www.example.org", false, 1, LOWEST));
[email protected]cdf8f7e72013-05-23 10:56:4611994 scoped_ptr<SpdyFrame> host2_req(
11995 spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4611996 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311997 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4611998 };
[email protected]23e482282013-06-14 16:08:0211999 scoped_ptr<SpdyFrame> host1_resp(
12000 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12001 scoped_ptr<SpdyFrame> host1_resp_body(
12002 spdy_util_.ConstructSpdyBodyFrame(1, true));
12003 scoped_ptr<SpdyFrame> host2_resp(
12004 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12005 scoped_ptr<SpdyFrame> host2_resp_body(
12006 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4612007 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312008 CreateMockRead(*host1_resp, 1),
12009 CreateMockRead(*host1_resp_body, 2),
12010 CreateMockRead(*host2_resp, 4),
12011 CreateMockRead(*host2_resp_body, 5),
12012 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4612013 };
12014
[email protected]d2b5f092012-06-08 23:55:0212015 IPAddressNumber ip;
12016 ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
12017 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12018 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1312019 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
12020 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712021 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4612022
[email protected]aa22b242011-11-16 18:58:2912023 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4612024 HttpRequestInfo request1;
12025 request1.method = "GET";
bncce36dca22015-04-21 22:11:2312026 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4612027 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012028 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612029
[email protected]49639fa2011-12-20 23:22:4112030 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612031 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112032 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612033
12034 const HttpResponseInfo* response = trans1.GetResponseInfo();
12035 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012036 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4612037 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12038
12039 std::string response_data;
12040 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
12041 EXPECT_EQ("hello!", response_data);
12042
12043 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1012044 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4612045 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1012046 rv = host_resolver.Resolve(resolve_info,
12047 DEFAULT_PRIORITY,
12048 &ignored,
12049 callback.callback(),
12050 NULL,
12051 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4712052 EXPECT_EQ(ERR_IO_PENDING, rv);
12053 rv = callback.WaitForResult();
12054 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4612055
12056 HttpRequestInfo request2;
12057 request2.method = "GET";
12058 request2.url = GURL("https://www.gmail.com/");
12059 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012060 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4612061
[email protected]49639fa2011-12-20 23:22:4112062 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4612063 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112064 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4612065
12066 response = trans2.GetResponseInfo();
12067 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012068 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]e3ceb682011-06-28 23:55:4612069 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12070 EXPECT_TRUE(response->was_fetched_via_spdy);
12071 EXPECT_TRUE(response->was_npn_negotiated);
12072 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
12073 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4612074}
12075
[email protected]23e482282013-06-14 16:08:0212076TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2312077 const std::string https_url = "https://www.example.org:8080/";
12078 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412079
12080 // SPDY GET for HTTPS URL
[email protected]cdf8f7e72013-05-23 10:56:4612081 scoped_ptr<SpdyFrame> req1(
12082 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0412083
12084 MockWrite writes1[] = {
12085 CreateMockWrite(*req1, 0),
12086 };
12087
[email protected]23e482282013-06-14 16:08:0212088 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12089 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8450d722012-07-02 19:14:0412090 MockRead reads1[] = {
12091 CreateMockRead(*resp1, 1),
12092 CreateMockRead(*body1, 2),
12093 MockRead(ASYNC, ERR_IO_PENDING, 3)
12094 };
12095
rch8e6c6c42015-05-01 14:05:1312096 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
12097 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412098 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712099 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412100
12101 // HTTP GET for the HTTP URL
12102 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1312103 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3412104 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2312105 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3412106 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0412107 };
12108
12109 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1312110 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
12111 MockRead(ASYNC, 2, "hello"),
12112 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0412113 };
12114
rch8e6c6c42015-05-01 14:05:1312115 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
12116 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0412117
[email protected]8450d722012-07-02 19:14:0412118 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212119 ssl.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712120 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12121 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12122 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0412123
[email protected]bb88e1d32013-05-03 23:11:0712124 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412125
12126 // Start the first transaction to set up the SpdySession
12127 HttpRequestInfo request1;
12128 request1.method = "GET";
12129 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412130 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012131 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412132 TestCompletionCallback callback1;
12133 EXPECT_EQ(ERR_IO_PENDING,
12134 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412135 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0412136
12137 EXPECT_EQ(OK, callback1.WaitForResult());
12138 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12139
12140 // Now, start the HTTP request
12141 HttpRequestInfo request2;
12142 request2.method = "GET";
12143 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412144 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012145 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412146 TestCompletionCallback callback2;
12147 EXPECT_EQ(ERR_IO_PENDING,
12148 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412149 base::MessageLoop::current()->RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0412150
12151 EXPECT_EQ(OK, callback2.WaitForResult());
12152 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12153}
12154
bnc1b0e36852015-04-28 15:32:5912155class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
12156 public:
12157 void Run(bool pooling, bool valid) {
12158 HostPortPair origin(valid ? "mail.example.org" : "invalid.example.org",
12159 443);
12160 HostPortPair alternative("www.example.org", 443);
12161
12162 base::FilePath certs_dir = GetTestCertsDirectory();
12163 scoped_refptr<X509Certificate> cert(
12164 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
12165 ASSERT_TRUE(cert.get());
12166 bool common_name_fallback_used;
12167 EXPECT_EQ(valid,
12168 cert->VerifyNameMatch(origin.host(), &common_name_fallback_used));
12169 EXPECT_TRUE(
12170 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
12171 SSLSocketDataProvider ssl(ASYNC, OK);
12172 ssl.SetNextProto(GetParam());
12173 ssl.cert = cert;
12174 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12175
12176 // If pooling, then start a request to alternative first to create a
12177 // SpdySession.
12178 std::string url0 = "https://www.example.org:443";
12179 // Second request to origin, which has an alternative service, and could
12180 // open a connection to the alternative host or pool to the existing one.
12181 std::string url1("https://");
12182 url1.append(origin.host());
12183 url1.append(":443");
12184
12185 scoped_ptr<SpdyFrame> req0;
12186 scoped_ptr<SpdyFrame> req1;
12187 scoped_ptr<SpdyFrame> resp0;
12188 scoped_ptr<SpdyFrame> body0;
12189 scoped_ptr<SpdyFrame> resp1;
12190 scoped_ptr<SpdyFrame> body1;
12191 std::vector<MockWrite> writes;
12192 std::vector<MockRead> reads;
12193
12194 if (pooling) {
12195 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), false, 1, LOWEST));
12196 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 3, LOWEST));
12197
12198 writes.push_back(CreateMockWrite(*req0, 0));
12199 writes.push_back(CreateMockWrite(*req1, 3));
12200
12201 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12202 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
12203 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12204 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
12205
12206 reads.push_back(CreateMockRead(*resp0, 1));
12207 reads.push_back(CreateMockRead(*body0, 2));
12208 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
12209 reads.push_back(CreateMockRead(*resp1, 5));
12210 reads.push_back(CreateMockRead(*body1, 6));
12211 reads.push_back(MockRead(ASYNC, OK, 7));
12212 } else {
12213 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), false, 1, LOWEST));
12214
12215 writes.push_back(CreateMockWrite(*req1, 0));
12216
12217 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12218 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
12219
12220 reads.push_back(CreateMockRead(*resp1, 1));
12221 reads.push_back(CreateMockRead(*body1, 2));
12222 reads.push_back(MockRead(ASYNC, OK, 3));
12223 }
12224
rch32320842015-05-16 15:57:0912225 SequencedSocketData data(vector_as_array(&reads), reads.size(),
12226 vector_as_array(&writes), writes.size());
bnc1b0e36852015-04-28 15:32:5912227 session_deps_.socket_factory->AddSocketDataProvider(&data);
12228
12229 // Connection to the origin fails.
12230 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12231 StaticSocketDataProvider data_refused;
12232 data_refused.set_connect_data(mock_connect);
12233 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12234
bnc55ff9da2015-08-19 18:42:3512235 session_deps_.use_alternative_services = true;
bnc1b0e36852015-04-28 15:32:5912236 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12237 base::WeakPtr<HttpServerProperties> http_server_properties =
12238 session->http_server_properties();
12239 AlternativeService alternative_service(
12240 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212241 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc1b0e36852015-04-28 15:32:5912242 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212243 1.0, expiration);
bnc1b0e36852015-04-28 15:32:5912244
12245 // First request to alternative.
12246 if (pooling) {
12247 scoped_ptr<HttpTransaction> trans0(
12248 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12249 HttpRequestInfo request0;
12250 request0.method = "GET";
12251 request0.url = GURL(url0);
12252 request0.load_flags = 0;
12253 TestCompletionCallback callback0;
12254
12255 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
12256 EXPECT_EQ(ERR_IO_PENDING, rv);
12257 rv = callback0.WaitForResult();
12258 EXPECT_EQ(OK, rv);
12259 }
12260
12261 // Second request to origin.
12262 scoped_ptr<HttpTransaction> trans1(
12263 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12264 HttpRequestInfo request1;
12265 request1.method = "GET";
12266 request1.url = GURL(url1);
12267 request1.load_flags = 0;
12268 TestCompletionCallback callback1;
12269
12270 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12271 EXPECT_EQ(ERR_IO_PENDING, rv);
rch32320842015-05-16 15:57:0912272 base::MessageLoop::current()->RunUntilIdle();
12273 if (data.IsReadPaused()) {
12274 data.CompleteRead();
12275 }
bnc1b0e36852015-04-28 15:32:5912276 rv = callback1.WaitForResult();
12277 if (valid) {
12278 EXPECT_EQ(OK, rv);
12279 } else {
12280 if (pooling) {
12281 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12282 } else {
12283 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
12284 }
12285 }
12286 }
12287};
12288
12289INSTANTIATE_TEST_CASE_P(NextProto,
12290 AltSvcCertificateVerificationTest,
12291 testing::Values(kProtoSPDY31,
bnc06d22432015-06-29 12:39:4312292 kProtoHTTP2));
bnc1b0e36852015-04-28 15:32:5912293
12294// The alternative service host must exhibit a certificate that is valid for the
12295// origin host. Test that this is enforced when pooling to an existing
12296// connection.
12297TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
12298 Run(true, true);
12299}
12300
12301TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
12302 Run(true, false);
12303}
12304
12305// The alternative service host must exhibit a certificate that is valid for the
12306// origin host. Test that this is enforced when opening a new connection.
12307TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
12308 Run(false, true);
12309}
12310
12311TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) {
12312 Run(false, false);
12313}
12314
bnc5452e2a2015-05-08 16:27:4212315// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
12316// with the alternative server. That connection should not be used.
12317TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
12318 HostPortPair origin("origin.example.org", 443);
12319 HostPortPair alternative("alternative.example.org", 443);
12320
12321 // Negotiate HTTP/1.1 with alternative.example.org.
12322 SSLSocketDataProvider ssl(ASYNC, OK);
12323 ssl.SetNextProto(kProtoHTTP11);
12324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12325
12326 // No data should be read from the alternative, because HTTP/1.1 is
12327 // negotiated.
12328 StaticSocketDataProvider data;
12329 session_deps_.socket_factory->AddSocketDataProvider(&data);
12330
12331 // This test documents that an alternate Job should not be used if HTTP/1.1 is
12332 // negotiated. In order to test this, a failed connection to the origin is
12333 // mocked. This way the request relies on the alternate Job.
12334 StaticSocketDataProvider data_refused;
12335 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12336 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12337
12338 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3512339 session_deps_.use_alternative_services = true;
bnc5452e2a2015-05-08 16:27:4212340 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12341 base::WeakPtr<HttpServerProperties> http_server_properties =
12342 session->http_server_properties();
12343 AlternativeService alternative_service(
12344 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212345 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4212346 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212347 1.0, expiration);
bnc5452e2a2015-05-08 16:27:4212348
12349 scoped_ptr<HttpTransaction> trans(
12350 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12351 HttpRequestInfo request;
12352 request.method = "GET";
12353 request.url = GURL("https://origin.example.org:443");
12354 request.load_flags = 0;
12355 TestCompletionCallback callback;
12356
12357 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
12358 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
12359 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12360 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
12361}
12362
bnc40448a532015-05-11 19:13:1412363// A request to a server with an alternative service fires two Jobs: one to the
12364// origin, and an alternate one to the alternative server. If the former
12365// succeeds, the request should succeed, even if the latter fails because
12366// HTTP/1.1 is negotiated which is insufficient for alternative service.
12367TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
12368 HostPortPair origin("origin.example.org", 443);
12369 HostPortPair alternative("alternative.example.org", 443);
12370
12371 // Negotiate HTTP/1.1 with alternative.
12372 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
12373 alternative_ssl.SetNextProto(kProtoHTTP11);
12374 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
12375
12376 // No data should be read from the alternative, because HTTP/1.1 is
12377 // negotiated.
12378 StaticSocketDataProvider data;
12379 session_deps_.socket_factory->AddSocketDataProvider(&data);
12380
12381 // Negotiate HTTP/1.1 with origin.
12382 SSLSocketDataProvider origin_ssl(ASYNC, OK);
12383 origin_ssl.SetNextProto(kProtoHTTP11);
12384 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
12385
12386 MockWrite http_writes[] = {
12387 MockWrite(
12388 "GET / HTTP/1.1\r\n"
12389 "Host: origin.example.org\r\n"
12390 "Connection: keep-alive\r\n\r\n"),
12391 MockWrite(
12392 "GET /second HTTP/1.1\r\n"
12393 "Host: origin.example.org\r\n"
12394 "Connection: keep-alive\r\n\r\n"),
12395 };
12396
12397 MockRead http_reads[] = {
12398 MockRead("HTTP/1.1 200 OK\r\n"),
12399 MockRead("Content-Type: text/html\r\n"),
12400 MockRead("Content-Length: 6\r\n\r\n"),
12401 MockRead("foobar"),
12402 MockRead("HTTP/1.1 200 OK\r\n"),
12403 MockRead("Content-Type: text/html\r\n"),
12404 MockRead("Content-Length: 7\r\n\r\n"),
12405 MockRead("another"),
12406 };
12407 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12408 http_writes, arraysize(http_writes));
12409 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12410
12411 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3512412 session_deps_.use_alternative_services = true;
bnc40448a532015-05-11 19:13:1412413 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12414 base::WeakPtr<HttpServerProperties> http_server_properties =
12415 session->http_server_properties();
12416 AlternativeService alternative_service(
12417 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212418 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc40448a532015-05-11 19:13:1412419 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212420 1.0, expiration);
bnc40448a532015-05-11 19:13:1412421
12422 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
12423 HttpRequestInfo request1;
12424 request1.method = "GET";
12425 request1.url = GURL("https://origin.example.org:443");
12426 request1.load_flags = 0;
12427 TestCompletionCallback callback1;
12428
12429 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
12430 rv = callback1.GetResult(rv);
12431 EXPECT_EQ(OK, rv);
12432
12433 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
12434 ASSERT_TRUE(response1 != nullptr);
12435 ASSERT_TRUE(response1->headers.get() != nullptr);
12436 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12437
12438 std::string response_data1;
12439 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data1));
12440 EXPECT_EQ("foobar", response_data1);
12441
12442 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
12443 // for alternative service.
12444 EXPECT_TRUE(
12445 http_server_properties->IsAlternativeServiceBroken(alternative_service));
12446
12447 // Since |alternative_service| is broken, a second transaction to origin
12448 // should not start an alternate Job. It should pool to existing connection
12449 // to origin.
12450 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
12451 HttpRequestInfo request2;
12452 request2.method = "GET";
12453 request2.url = GURL("https://origin.example.org:443/second");
12454 request2.load_flags = 0;
12455 TestCompletionCallback callback2;
12456
12457 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
12458 rv = callback2.GetResult(rv);
12459 EXPECT_EQ(OK, rv);
12460
12461 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
12462 ASSERT_TRUE(response2 != nullptr);
12463 ASSERT_TRUE(response2->headers.get() != nullptr);
12464 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
12465
12466 std::string response_data2;
12467 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data2));
12468 EXPECT_EQ("another", response_data2);
12469}
12470
bnc5452e2a2015-05-08 16:27:4212471// Alternative service requires HTTP/2 (or SPDY), but there is already a
12472// HTTP/1.1 socket open to the alternative server. That socket should not be
12473// used.
12474TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
12475 HostPortPair origin("origin.example.org", 443);
12476 HostPortPair alternative("alternative.example.org", 443);
12477 std::string origin_url = "https://origin.example.org:443";
12478 std::string alternative_url = "https://alternative.example.org:443";
12479
12480 // Negotiate HTTP/1.1 with alternative.example.org.
12481 SSLSocketDataProvider ssl(ASYNC, OK);
12482 ssl.SetNextProto(kProtoHTTP11);
12483 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12484
12485 // HTTP/1.1 data for |request1| and |request2|.
12486 MockWrite http_writes[] = {
12487 MockWrite(
12488 "GET / HTTP/1.1\r\n"
12489 "Host: alternative.example.org\r\n"
12490 "Connection: keep-alive\r\n\r\n"),
12491 MockWrite(
12492 "GET / HTTP/1.1\r\n"
12493 "Host: alternative.example.org\r\n"
12494 "Connection: keep-alive\r\n\r\n"),
12495 };
12496
12497 MockRead http_reads[] = {
12498 MockRead(
12499 "HTTP/1.1 200 OK\r\n"
12500 "Content-Type: text/html; charset=iso-8859-1\r\n"
12501 "Content-Length: 40\r\n\r\n"
12502 "first HTTP/1.1 response from alternative"),
12503 MockRead(
12504 "HTTP/1.1 200 OK\r\n"
12505 "Content-Type: text/html; charset=iso-8859-1\r\n"
12506 "Content-Length: 41\r\n\r\n"
12507 "second HTTP/1.1 response from alternative"),
12508 };
12509 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12510 http_writes, arraysize(http_writes));
12511 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12512
12513 // This test documents that an alternate Job should not pool to an already
12514 // existing HTTP/1.1 connection. In order to test this, a failed connection
12515 // to the origin is mocked. This way |request2| relies on the alternate Job.
12516 StaticSocketDataProvider data_refused;
12517 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12518 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12519
12520 // Set up alternative service for origin.
bnc55ff9da2015-08-19 18:42:3512521 session_deps_.use_alternative_services = true;
bnc5452e2a2015-05-08 16:27:4212522 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12523 base::WeakPtr<HttpServerProperties> http_server_properties =
12524 session->http_server_properties();
12525 AlternativeService alternative_service(
12526 AlternateProtocolFromNextProto(GetParam()), alternative);
bnc7dc7e1b42015-07-28 14:43:1212527 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc5452e2a2015-05-08 16:27:4212528 http_server_properties->SetAlternativeService(origin, alternative_service,
bnc7dc7e1b42015-07-28 14:43:1212529 1.0, expiration);
bnc5452e2a2015-05-08 16:27:4212530
12531 // First transaction to alternative to open an HTTP/1.1 socket.
12532 scoped_ptr<HttpTransaction> trans1(
12533 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12534 HttpRequestInfo request1;
12535 request1.method = "GET";
12536 request1.url = GURL(alternative_url);
12537 request1.load_flags = 0;
12538 TestCompletionCallback callback1;
12539
12540 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12541 EXPECT_EQ(OK, callback1.GetResult(rv));
12542 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12543 ASSERT_TRUE(response1);
12544 ASSERT_TRUE(response1->headers.get());
12545 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12546 EXPECT_TRUE(response1->was_npn_negotiated);
12547 EXPECT_FALSE(response1->was_fetched_via_spdy);
12548 std::string response_data1;
12549 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
12550 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
12551
12552 // Request for origin.example.org, which has an alternative service. This
12553 // will start two Jobs: the alternative looks for connections to pool to,
12554 // finds one which is HTTP/1.1, and should ignore it, and should not try to
12555 // open other connections to alternative server. The Job to origin fails, so
12556 // this request fails.
12557 scoped_ptr<HttpTransaction> trans2(
12558 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12559 HttpRequestInfo request2;
12560 request2.method = "GET";
12561 request2.url = GURL(origin_url);
12562 request2.load_flags = 0;
12563 TestCompletionCallback callback2;
12564
12565 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
12566 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
12567
12568 // Another transaction to alternative. This is to test that the HTTP/1.1
12569 // socket is still open and in the pool.
12570 scoped_ptr<HttpTransaction> trans3(
12571 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12572 HttpRequestInfo request3;
12573 request3.method = "GET";
12574 request3.url = GURL(alternative_url);
12575 request3.load_flags = 0;
12576 TestCompletionCallback callback3;
12577
12578 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
12579 EXPECT_EQ(OK, callback3.GetResult(rv));
12580 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
12581 ASSERT_TRUE(response3);
12582 ASSERT_TRUE(response3->headers.get());
12583 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
12584 EXPECT_TRUE(response3->was_npn_negotiated);
12585 EXPECT_FALSE(response3->was_fetched_via_spdy);
12586 std::string response_data3;
12587 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
12588 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
12589}
12590
[email protected]23e482282013-06-14 16:08:0212591TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2312592 const std::string https_url = "https://www.example.org:8080/";
12593 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0412594
12595 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2312596 const HostPortPair host_port_pair("www.example.org", 8080);
lgarrona91df87f2014-12-05 00:51:3412597 scoped_ptr<SpdyFrame> connect(
12598 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
[email protected]cdf8f7e72013-05-23 10:56:4612599 scoped_ptr<SpdyFrame> req1(
12600 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
[email protected]23e482282013-06-14 16:08:0212601 scoped_ptr<SpdyFrame> wrapped_req1(
12602 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3912603
12604 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2912605 SpdyHeaderBlock req2_block;
12606 req2_block[spdy_util_.GetMethodKey()] = "GET";
bnc33b8cef42014-11-19 17:30:3812607 req2_block[spdy_util_.GetPathKey()] = "/";
bncce36dca22015-04-21 22:11:2312608 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2912609 req2_block[spdy_util_.GetSchemeKey()] = "http";
12610 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]601e03f12014-04-06 16:26:3912611 scoped_ptr<SpdyFrame> req2(
[email protected]745aa9c2014-06-27 02:21:2912612 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
[email protected]8450d722012-07-02 19:14:0412613
12614 MockWrite writes1[] = {
12615 CreateMockWrite(*connect, 0),
12616 CreateMockWrite(*wrapped_req1, 2),
12617 CreateMockWrite(*req2, 5),
12618 };
12619
[email protected]23e482282013-06-14 16:08:0212620 scoped_ptr<SpdyFrame> conn_resp(
12621 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12622 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12623 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
12624 scoped_ptr<SpdyFrame> wrapped_resp1(
12625 spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
12626 scoped_ptr<SpdyFrame> wrapped_body1(
12627 spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
12628 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
12629 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]8450d722012-07-02 19:14:0412630 MockRead reads1[] = {
12631 CreateMockRead(*conn_resp, 1),
12632 CreateMockRead(*wrapped_resp1, 3),
12633 CreateMockRead(*wrapped_body1, 4),
12634 CreateMockRead(*resp2, 6),
12635 CreateMockRead(*body2, 7),
12636 MockRead(ASYNC, ERR_IO_PENDING, 8)
12637 };
12638
[email protected]dd54bd82012-07-19 23:44:5712639 DeterministicSocketData data1(reads1, arraysize(reads1),
12640 writes1, arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0412641 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5712642 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0412643
[email protected]bb88e1d32013-05-03 23:11:0712644 session_deps_.proxy_service.reset(
[email protected]f6c63db52013-02-02 00:35:2212645 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
vishal.b62985ca92015-04-17 08:45:5112646 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712647 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0412648 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
[email protected]23e482282013-06-14 16:08:0212649 ssl1.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712650 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0412651 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212652 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712653 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12654 session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0412655
12656 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712657 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]8450d722012-07-02 19:14:0412658
12659 // Start the first transaction to set up the SpdySession
12660 HttpRequestInfo request1;
12661 request1.method = "GET";
12662 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0412663 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012664 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0412665 TestCompletionCallback callback1;
12666 EXPECT_EQ(ERR_IO_PENDING,
12667 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412668 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712669 data1.RunFor(4);
[email protected]8450d722012-07-02 19:14:0412670
12671 EXPECT_EQ(OK, callback1.WaitForResult());
12672 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12673
[email protected]f6c63db52013-02-02 00:35:2212674 LoadTimingInfo load_timing_info1;
12675 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
12676 TestLoadTimingNotReusedWithPac(load_timing_info1,
12677 CONNECT_TIMING_HAS_SSL_TIMES);
12678
[email protected]8450d722012-07-02 19:14:0412679 // Now, start the HTTP request
12680 HttpRequestInfo request2;
12681 request2.method = "GET";
12682 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0412683 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012684 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0412685 TestCompletionCallback callback2;
12686 EXPECT_EQ(ERR_IO_PENDING,
12687 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412688 base::MessageLoop::current()->RunUntilIdle();
[email protected]dd54bd82012-07-19 23:44:5712689 data1.RunFor(3);
[email protected]8450d722012-07-02 19:14:0412690
12691 EXPECT_EQ(OK, callback2.WaitForResult());
12692 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2212693
12694 LoadTimingInfo load_timing_info2;
12695 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
12696 // The established SPDY sessions is considered reused by the HTTP request.
12697 TestLoadTimingReusedWithPac(load_timing_info2);
12698 // HTTP requests over a SPDY session should have a different connection
12699 // socket_log_id than requests over a tunnel.
12700 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0412701}
12702
[email protected]2d88e7d2012-07-19 17:55:1712703// Test that in the case where we have a SPDY session to a SPDY proxy
12704// that we do not pool other origins that resolve to the same IP when
12705// the certificate does not match the new origin.
12706// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0212707TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2312708 const std::string url1 = "http://www.example.org/";
12709 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1712710 const std::string ip_addr = "1.2.3.4";
12711
12712 // SPDY GET for HTTP URL (through SPDY proxy)
[email protected]23e482282013-06-14 16:08:0212713 scoped_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2312714 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
[email protected]745aa9c2014-06-27 02:21:2912715 scoped_ptr<SpdyFrame> req1(
12716 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
[email protected]2d88e7d2012-07-19 17:55:1712717
12718 MockWrite writes1[] = {
12719 CreateMockWrite(*req1, 0),
12720 };
12721
[email protected]23e482282013-06-14 16:08:0212722 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12723 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712724 MockRead reads1[] = {
bncb9e20fc62015-08-17 17:19:3712725 CreateMockRead(*resp1, 1),
12726 CreateMockRead(*body1, 2),
12727 MockRead(ASYNC, OK, 3) // EOF
[email protected]2d88e7d2012-07-19 17:55:1712728 };
12729
12730 scoped_ptr<DeterministicSocketData> data1(
12731 new DeterministicSocketData(reads1, arraysize(reads1),
12732 writes1, arraysize(writes1)));
12733 IPAddressNumber ip;
12734 ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
12735 IPEndPoint peer_addr = IPEndPoint(ip, 443);
12736 MockConnect connect_data1(ASYNC, OK, peer_addr);
12737 data1->set_connect_data(connect_data1);
12738
12739 // SPDY GET for HTTPS URL (direct)
[email protected]cdf8f7e72013-05-23 10:56:4612740 scoped_ptr<SpdyFrame> req2(
12741 spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1712742
12743 MockWrite writes2[] = {
12744 CreateMockWrite(*req2, 0),
12745 };
12746
[email protected]23e482282013-06-14 16:08:0212747 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12748 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1712749 MockRead reads2[] = {
bncb9e20fc62015-08-17 17:19:3712750 CreateMockRead(*resp2, 1),
12751 CreateMockRead(*body2, 2),
12752 MockRead(ASYNC, OK, 3) // EOF
[email protected]2d88e7d2012-07-19 17:55:1712753 };
12754
12755 scoped_ptr<DeterministicSocketData> data2(
12756 new DeterministicSocketData(reads2, arraysize(reads2),
12757 writes2, arraysize(writes2)));
12758 MockConnect connect_data2(ASYNC, OK);
12759 data2->set_connect_data(connect_data2);
12760
12761 // Set up a proxy config that sends HTTP requests to a proxy, and
12762 // all others direct.
12763 ProxyConfig proxy_config;
12764 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0712765 session_deps_.proxy_service.reset(new ProxyService(
sammc5dd160c2015-04-02 02:43:1312766 new ProxyConfigServiceFixed(proxy_config), nullptr, NULL));
[email protected]2d88e7d2012-07-19 17:55:1712767
bncce36dca22015-04-21 22:11:2312768 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
12769 ssl1.SetNextProto(GetParam());
[email protected]2d88e7d2012-07-19 17:55:1712770 // Load a valid cert. Note, that this does not need to
12771 // be valid for proxy because the MockSSLClientSocket does
12772 // not actually verify it. But SpdySession will use this
12773 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2312774 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
12775 ASSERT_TRUE(ssl1.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0712776 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
12777 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12778 data1.get());
[email protected]2d88e7d2012-07-19 17:55:1712779
12780 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
[email protected]23e482282013-06-14 16:08:0212781 ssl2.SetNextProto(GetParam());
[email protected]bb88e1d32013-05-03 23:11:0712782 session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
12783 session_deps_.deterministic_socket_factory->AddSocketDataProvider(
12784 data2.get());
[email protected]2d88e7d2012-07-19 17:55:1712785
[email protected]bb88e1d32013-05-03 23:11:0712786 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2312787 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0712788 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1712789
12790 scoped_refptr<HttpNetworkSession> session(
[email protected]bb88e1d32013-05-03 23:11:0712791 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
[email protected]2d88e7d2012-07-19 17:55:1712792
12793 // Start the first transaction to set up the SpdySession
12794 HttpRequestInfo request1;
12795 request1.method = "GET";
12796 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1712797 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012798 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712799 TestCompletionCallback callback1;
12800 ASSERT_EQ(ERR_IO_PENDING,
12801 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
12802 data1->RunFor(3);
12803
12804 ASSERT_TRUE(callback1.have_result());
12805 EXPECT_EQ(OK, callback1.WaitForResult());
12806 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
12807
12808 // Now, start the HTTP request
12809 HttpRequestInfo request2;
12810 request2.method = "GET";
12811 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1712812 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012813 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1712814 TestCompletionCallback callback2;
12815 EXPECT_EQ(ERR_IO_PENDING,
12816 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]2da659e2013-05-23 20:51:3412817 base::MessageLoop::current()->RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1712818 data2->RunFor(3);
12819
12820 ASSERT_TRUE(callback2.have_result());
12821 EXPECT_EQ(OK, callback2.WaitForResult());
12822 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12823}
12824
[email protected]85f97342013-04-17 06:12:2412825// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
12826// error) in SPDY session, removes the socket from pool and closes the SPDY
12827// session. Verify that new url's from the same HttpNetworkSession (and a new
12828// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0212829TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2312830 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2412831
12832 MockRead reads1[] = {
12833 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
12834 };
12835
mmenke11eb5152015-06-09 14:50:5012836 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2412837
[email protected]cdf8f7e72013-05-23 10:56:4612838 scoped_ptr<SpdyFrame> req2(
12839 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2412840 MockWrite writes2[] = {
12841 CreateMockWrite(*req2, 0),
12842 };
12843
[email protected]23e482282013-06-14 16:08:0212844 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12845 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2412846 MockRead reads2[] = {
12847 CreateMockRead(*resp2, 1),
12848 CreateMockRead(*body2, 2),
12849 MockRead(ASYNC, OK, 3) // EOF
12850 };
12851
mmenke11eb5152015-06-09 14:50:5012852 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
12853 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2412854
[email protected]85f97342013-04-17 06:12:2412855 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212856 ssl1.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5012857 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12858 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2412859
12860 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212861 ssl2.SetNextProto(GetParam());
mmenke11eb5152015-06-09 14:50:5012862 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12863 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2412864
12865 scoped_refptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5012866 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2412867
12868 // Start the first transaction to set up the SpdySession and verify that
12869 // connection was closed.
12870 HttpRequestInfo request1;
12871 request1.method = "GET";
12872 request1.url = GURL(https_url);
12873 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012874 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412875 TestCompletionCallback callback1;
12876 EXPECT_EQ(ERR_IO_PENDING,
12877 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2412878 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
12879
12880 // Now, start the second request and make sure it succeeds.
12881 HttpRequestInfo request2;
12882 request2.method = "GET";
12883 request2.url = GURL(https_url);
12884 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5012885 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2412886 TestCompletionCallback callback2;
12887 EXPECT_EQ(ERR_IO_PENDING,
12888 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2412889
mmenke11eb5152015-06-09 14:50:5012890 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]85f97342013-04-17 06:12:2412891 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
12892}
12893
[email protected]23e482282013-06-14 16:08:0212894TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]d7599122014-05-24 03:37:2312895 session_deps_.next_protos = SpdyNextProtos();
[email protected]483fa202013-05-14 01:07:0312896 ClientSocketPoolManager::set_max_sockets_per_group(
12897 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12898 ClientSocketPoolManager::set_max_sockets_per_pool(
12899 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
12900
12901 // Use two different hosts with different IPs so they don't get pooled.
12902 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
12903 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
12904 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12905
12906 SSLSocketDataProvider ssl1(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212907 ssl1.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312908 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]23e482282013-06-14 16:08:0212909 ssl2.SetNextProto(GetParam());
[email protected]483fa202013-05-14 01:07:0312910 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
12911 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
12912
[email protected]cdf8f7e72013-05-23 10:56:4612913 scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312914 "https://www.a.com", false, 1, DEFAULT_PRIORITY));
12915 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1312916 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0312917 };
[email protected]23e482282013-06-14 16:08:0212918 scoped_ptr<SpdyFrame> host1_resp(
12919 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12920 scoped_ptr<SpdyFrame> host1_resp_body(
12921 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312922 MockRead spdy1_reads[] = {
rch8e6c6c42015-05-01 14:05:1312923 CreateMockRead(*host1_resp, 1),
12924 CreateMockRead(*host1_resp_body, 2),
12925 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312926 };
12927
rch8e6c6c42015-05-01 14:05:1312928 scoped_ptr<SequencedSocketData> spdy1_data(
12929 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
12930 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0312931 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
12932
[email protected]cdf8f7e72013-05-23 10:56:4612933 scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
[email protected]483fa202013-05-14 01:07:0312934 "https://www.b.com", false, 1, DEFAULT_PRIORITY));
12935 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1312936 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0312937 };
[email protected]23e482282013-06-14 16:08:0212938 scoped_ptr<SpdyFrame> host2_resp(
12939 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
12940 scoped_ptr<SpdyFrame> host2_resp_body(
12941 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0312942 MockRead spdy2_reads[] = {
rch8e6c6c42015-05-01 14:05:1312943 CreateMockRead(*host2_resp, 1),
12944 CreateMockRead(*host2_resp_body, 2),
12945 MockRead(ASYNC, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0312946 };
12947
rch8e6c6c42015-05-01 14:05:1312948 scoped_ptr<SequencedSocketData> spdy2_data(
12949 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
12950 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0312951 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
12952
12953 MockWrite http_write[] = {
12954 MockWrite("GET / HTTP/1.1\r\n"
12955 "Host: www.a.com\r\n"
12956 "Connection: keep-alive\r\n\r\n"),
12957 };
12958
12959 MockRead http_read[] = {
12960 MockRead("HTTP/1.1 200 OK\r\n"),
12961 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12962 MockRead("Content-Length: 6\r\n\r\n"),
12963 MockRead("hello!"),
12964 };
12965 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
12966 http_write, arraysize(http_write));
12967 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12968
12969 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4012970 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5312971 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0312972 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2612973 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0312974
12975 TestCompletionCallback callback;
12976 HttpRequestInfo request1;
12977 request1.method = "GET";
12978 request1.url = GURL("https://www.a.com/");
12979 request1.load_flags = 0;
12980 scoped_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5012981 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0312982
12983 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
12984 EXPECT_EQ(ERR_IO_PENDING, rv);
12985 EXPECT_EQ(OK, callback.WaitForResult());
12986
12987 const HttpResponseInfo* response = trans->GetResponseInfo();
12988 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5012989 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0312990 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12991 EXPECT_TRUE(response->was_fetched_via_spdy);
12992 EXPECT_TRUE(response->was_npn_negotiated);
12993
12994 std::string response_data;
12995 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12996 EXPECT_EQ("hello!", response_data);
12997 trans.reset();
12998 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2612999 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313000
13001 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4013002 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5313003 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313004 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613005 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313006 HttpRequestInfo request2;
13007 request2.method = "GET";
13008 request2.url = GURL("https://www.b.com/");
13009 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013010 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313011
13012 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
13013 EXPECT_EQ(ERR_IO_PENDING, rv);
13014 EXPECT_EQ(OK, callback.WaitForResult());
13015
13016 response = trans->GetResponseInfo();
13017 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013018 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0313019 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13020 EXPECT_TRUE(response->was_fetched_via_spdy);
13021 EXPECT_TRUE(response->was_npn_negotiated);
13022 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13023 EXPECT_EQ("hello!", response_data);
13024 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613025 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313026 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2613027 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313028
13029 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4013030 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5313031 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0313032 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613033 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0313034 HttpRequestInfo request3;
13035 request3.method = "GET";
13036 request3.url = GURL("http://www.a.com/");
13037 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013038 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0313039
13040 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
13041 EXPECT_EQ(ERR_IO_PENDING, rv);
13042 EXPECT_EQ(OK, callback.WaitForResult());
13043
13044 response = trans->GetResponseInfo();
13045 ASSERT_TRUE(response != NULL);
[email protected]90499482013-06-01 00:39:5013046 ASSERT_TRUE(response->headers.get() != NULL);
[email protected]483fa202013-05-14 01:07:0313047 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13048 EXPECT_FALSE(response->was_fetched_via_spdy);
13049 EXPECT_FALSE(response->was_npn_negotiated);
13050 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
13051 EXPECT_EQ("hello!", response_data);
13052 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613053 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0313054 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2613055 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0313056}
13057
[email protected]79e1fd62013-06-20 06:50:0413058TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
13059 HttpRequestInfo request;
13060 request.method = "GET";
bncce36dca22015-04-21 22:11:2313061 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413062 request.load_flags = 0;
13063
[email protected]3fe8d2f82013-10-17 08:56:0713064 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413065 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113066 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413067
13068 MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
13069 StaticSocketDataProvider data;
13070 data.set_connect_data(mock_connect);
13071 session_deps_.socket_factory->AddSocketDataProvider(&data);
13072
13073 TestCompletionCallback callback;
13074
13075 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13076 EXPECT_EQ(ERR_IO_PENDING, rv);
13077
13078 rv = callback.WaitForResult();
13079 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
13080
[email protected]79e1fd62013-06-20 06:50:0413081 // We don't care whether this succeeds or fails, but it shouldn't crash.
13082 HttpRequestHeaders request_headers;
13083 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713084
13085 ConnectionAttempts attempts;
13086 trans->GetConnectionAttempts(&attempts);
13087 ASSERT_EQ(1u, attempts.size());
13088 EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
[email protected]79e1fd62013-06-20 06:50:0413089}
13090
13091TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
13092 HttpRequestInfo request;
13093 request.method = "GET";
bncce36dca22015-04-21 22:11:2313094 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413095 request.load_flags = 0;
13096
[email protected]3fe8d2f82013-10-17 08:56:0713097 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413098 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113099 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413100
13101 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
13102 StaticSocketDataProvider data;
13103 data.set_connect_data(mock_connect);
13104 session_deps_.socket_factory->AddSocketDataProvider(&data);
13105
13106 TestCompletionCallback callback;
13107
13108 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13109 EXPECT_EQ(ERR_IO_PENDING, rv);
13110
13111 rv = callback.WaitForResult();
13112 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
13113
[email protected]79e1fd62013-06-20 06:50:0413114 // We don't care whether this succeeds or fails, but it shouldn't crash.
13115 HttpRequestHeaders request_headers;
13116 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4713117
13118 ConnectionAttempts attempts;
13119 trans->GetConnectionAttempts(&attempts);
13120 ASSERT_EQ(1u, attempts.size());
13121 EXPECT_EQ(ERR_CONNECTION_REFUSED, attempts[0].result);
[email protected]79e1fd62013-06-20 06:50:0413122}
13123
13124TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
13125 HttpRequestInfo request;
13126 request.method = "GET";
bncce36dca22015-04-21 22:11:2313127 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413128 request.load_flags = 0;
13129
[email protected]3fe8d2f82013-10-17 08:56:0713130 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413131 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113132 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413133
13134 MockWrite data_writes[] = {
13135 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13136 };
13137 MockRead data_reads[] = {
13138 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
13139 };
13140
13141 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13142 data_writes, arraysize(data_writes));
13143 session_deps_.socket_factory->AddSocketDataProvider(&data);
13144
13145 TestCompletionCallback callback;
13146
13147 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13148 EXPECT_EQ(ERR_IO_PENDING, rv);
13149
13150 rv = callback.WaitForResult();
13151 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13152
[email protected]79e1fd62013-06-20 06:50:0413153 HttpRequestHeaders request_headers;
13154 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13155 EXPECT_TRUE(request_headers.HasHeader("Host"));
13156}
13157
13158TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
13159 HttpRequestInfo request;
13160 request.method = "GET";
bncce36dca22015-04-21 22:11:2313161 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413162 request.load_flags = 0;
13163
[email protected]3fe8d2f82013-10-17 08:56:0713164 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413165 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113166 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413167
13168 MockWrite data_writes[] = {
13169 MockWrite(ASYNC, ERR_CONNECTION_RESET),
13170 };
13171 MockRead data_reads[] = {
13172 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
13173 };
13174
13175 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13176 data_writes, arraysize(data_writes));
13177 session_deps_.socket_factory->AddSocketDataProvider(&data);
13178
13179 TestCompletionCallback callback;
13180
13181 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13182 EXPECT_EQ(ERR_IO_PENDING, rv);
13183
13184 rv = callback.WaitForResult();
13185 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13186
[email protected]79e1fd62013-06-20 06:50:0413187 HttpRequestHeaders request_headers;
13188 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13189 EXPECT_TRUE(request_headers.HasHeader("Host"));
13190}
13191
13192TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
13193 HttpRequestInfo request;
13194 request.method = "GET";
bncce36dca22015-04-21 22:11:2313195 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413196 request.load_flags = 0;
13197
[email protected]3fe8d2f82013-10-17 08:56:0713198 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413199 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113200 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413201
13202 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313203 MockWrite(
13204 "GET / HTTP/1.1\r\n"
13205 "Host: www.example.org\r\n"
13206 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413207 };
13208 MockRead data_reads[] = {
13209 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
13210 };
13211
13212 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13213 data_writes, arraysize(data_writes));
13214 session_deps_.socket_factory->AddSocketDataProvider(&data);
13215
13216 TestCompletionCallback callback;
13217
13218 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13219 EXPECT_EQ(ERR_IO_PENDING, rv);
13220
13221 rv = callback.WaitForResult();
13222 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13223
[email protected]79e1fd62013-06-20 06:50:0413224 HttpRequestHeaders request_headers;
13225 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13226 EXPECT_TRUE(request_headers.HasHeader("Host"));
13227}
13228
13229TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
13230 HttpRequestInfo request;
13231 request.method = "GET";
bncce36dca22015-04-21 22:11:2313232 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413233 request.load_flags = 0;
13234
[email protected]3fe8d2f82013-10-17 08:56:0713235 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413236 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113237 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413238
13239 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313240 MockWrite(
13241 "GET / HTTP/1.1\r\n"
13242 "Host: www.example.org\r\n"
13243 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413244 };
13245 MockRead data_reads[] = {
13246 MockRead(ASYNC, ERR_CONNECTION_RESET),
13247 };
13248
13249 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13250 data_writes, arraysize(data_writes));
13251 session_deps_.socket_factory->AddSocketDataProvider(&data);
13252
13253 TestCompletionCallback callback;
13254
13255 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13256 EXPECT_EQ(ERR_IO_PENDING, rv);
13257
13258 rv = callback.WaitForResult();
13259 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
13260
[email protected]79e1fd62013-06-20 06:50:0413261 HttpRequestHeaders request_headers;
13262 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13263 EXPECT_TRUE(request_headers.HasHeader("Host"));
13264}
13265
13266TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
13267 HttpRequestInfo request;
13268 request.method = "GET";
bncce36dca22015-04-21 22:11:2313269 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0413270 request.load_flags = 0;
13271 request.extra_headers.SetHeader("X-Foo", "bar");
13272
[email protected]3fe8d2f82013-10-17 08:56:0713273 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]79e1fd62013-06-20 06:50:0413274 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113275 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0413276
13277 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313278 MockWrite(
13279 "GET / HTTP/1.1\r\n"
13280 "Host: www.example.org\r\n"
13281 "Connection: keep-alive\r\n"
13282 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0413283 };
13284 MockRead data_reads[] = {
13285 MockRead("HTTP/1.1 200 OK\r\n"
13286 "Content-Length: 5\r\n\r\n"
13287 "hello"),
13288 MockRead(ASYNC, ERR_UNEXPECTED),
13289 };
13290
13291 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
13292 data_writes, arraysize(data_writes));
13293 session_deps_.socket_factory->AddSocketDataProvider(&data);
13294
13295 TestCompletionCallback callback;
13296
13297 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13298 EXPECT_EQ(ERR_IO_PENDING, rv);
13299
13300 rv = callback.WaitForResult();
13301 EXPECT_EQ(OK, rv);
13302
13303 HttpRequestHeaders request_headers;
13304 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
13305 std::string foo;
13306 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
13307 EXPECT_EQ("bar", foo);
13308}
13309
[email protected]bf828982013-08-14 18:01:4713310namespace {
13311
yhiranoa7e05bb2014-11-06 05:40:3913312// Fake HttpStream that simply records calls to SetPriority().
13313class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0313314 public base::SupportsWeakPtr<FakeStream> {
13315 public:
13316 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2013317 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0313318
13319 RequestPriority priority() const { return priority_; }
13320
dchengb03027d2014-10-21 12:00:2013321 int InitializeStream(const HttpRequestInfo* request_info,
13322 RequestPriority priority,
13323 const BoundNetLog& net_log,
13324 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313325 return ERR_IO_PENDING;
13326 }
13327
dchengb03027d2014-10-21 12:00:2013328 int SendRequest(const HttpRequestHeaders& request_headers,
13329 HttpResponseInfo* response,
13330 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313331 ADD_FAILURE();
13332 return ERR_UNEXPECTED;
13333 }
13334
dchengb03027d2014-10-21 12:00:2013335 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313336 ADD_FAILURE();
13337 return ERR_UNEXPECTED;
13338 }
13339
dchengb03027d2014-10-21 12:00:2013340 int ReadResponseBody(IOBuffer* buf,
13341 int buf_len,
13342 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0313343 ADD_FAILURE();
13344 return ERR_UNEXPECTED;
13345 }
13346
dchengb03027d2014-10-21 12:00:2013347 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0313348
dchengb03027d2014-10-21 12:00:2013349 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0313350 ADD_FAILURE();
13351 return false;
13352 }
13353
dchengb03027d2014-10-21 12:00:2013354 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0313355 ADD_FAILURE();
13356 return false;
13357 }
13358
dchengb03027d2014-10-21 12:00:2013359 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0313360
mmenkebd84c392015-09-02 14:12:3413361 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0313362
dchengb03027d2014-10-21 12:00:2013363 int64 GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5913364 ADD_FAILURE();
13365 return 0;
13366 }
13367
sclittlebe1ccf62015-09-02 19:40:3613368 int64_t GetTotalSentBytes() const override {
13369 ADD_FAILURE();
13370 return 0;
13371 }
13372
dchengb03027d2014-10-21 12:00:2013373 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0313374 ADD_FAILURE();
13375 return false;
13376 }
13377
dchengb03027d2014-10-21 12:00:2013378 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
13379
13380 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0313381 ADD_FAILURE();
13382 }
13383
dchengb03027d2014-10-21 12:00:2013384 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0313385
dchengb03027d2014-10-21 12:00:2013386 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0313387
yhiranoa7e05bb2014-11-06 05:40:3913388 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
13389
13390 HttpStream* RenewStreamForAuth() override { return NULL; }
13391
[email protected]e86839fd2013-08-14 18:29:0313392 private:
13393 RequestPriority priority_;
13394
13395 DISALLOW_COPY_AND_ASSIGN(FakeStream);
13396};
13397
13398// Fake HttpStreamRequest that simply records calls to SetPriority()
13399// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4713400class FakeStreamRequest : public HttpStreamRequest,
13401 public base::SupportsWeakPtr<FakeStreamRequest> {
13402 public:
[email protected]e86839fd2013-08-14 18:29:0313403 FakeStreamRequest(RequestPriority priority,
13404 HttpStreamRequest::Delegate* delegate)
13405 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4413406 delegate_(delegate),
13407 websocket_stream_create_helper_(NULL) {}
13408
13409 FakeStreamRequest(RequestPriority priority,
13410 HttpStreamRequest::Delegate* delegate,
13411 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
13412 : priority_(priority),
13413 delegate_(delegate),
13414 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0313415
dchengb03027d2014-10-21 12:00:2013416 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4713417
13418 RequestPriority priority() const { return priority_; }
13419
[email protected]831e4a32013-11-14 02:14:4413420 const WebSocketHandshakeStreamBase::CreateHelper*
13421 websocket_stream_create_helper() const {
13422 return websocket_stream_create_helper_;
13423 }
13424
[email protected]e86839fd2013-08-14 18:29:0313425 // Create a new FakeStream and pass it to the request's
13426 // delegate. Returns a weak pointer to the FakeStream.
13427 base::WeakPtr<FakeStream> FinishStreamRequest() {
13428 FakeStream* fake_stream = new FakeStream(priority_);
13429 // Do this before calling OnStreamReady() as OnStreamReady() may
13430 // immediately delete |fake_stream|.
13431 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
13432 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
13433 return weak_stream;
13434 }
13435
dchengb03027d2014-10-21 12:00:2013436 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4713437 ADD_FAILURE();
13438 return ERR_UNEXPECTED;
13439 }
13440
dchengb03027d2014-10-21 12:00:2013441 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4713442 ADD_FAILURE();
13443 return LoadState();
13444 }
13445
dchengb03027d2014-10-21 12:00:2013446 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4713447
dchengb03027d2014-10-21 12:00:2013448 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713449
dchengb03027d2014-10-21 12:00:2013450 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4713451
dchengb03027d2014-10-21 12:00:2013452 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4713453
ttuttle1f2d7e92015-04-28 16:17:4713454 const ConnectionAttempts& connection_attempts() const override {
13455 static ConnectionAttempts no_attempts;
13456 return no_attempts;
13457 }
13458
[email protected]bf828982013-08-14 18:01:4713459 private:
13460 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0313461 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4413462 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4713463
13464 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
13465};
13466
13467// Fake HttpStreamFactory that vends FakeStreamRequests.
13468class FakeStreamFactory : public HttpStreamFactory {
13469 public:
13470 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2013471 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4713472
13473 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
13474 // RequestStream() (which may be NULL if it was destroyed already).
13475 base::WeakPtr<FakeStreamRequest> last_stream_request() {
13476 return last_stream_request_;
13477 }
13478
dchengb03027d2014-10-21 12:00:2013479 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
13480 RequestPriority priority,
13481 const SSLConfig& server_ssl_config,
13482 const SSLConfig& proxy_ssl_config,
13483 HttpStreamRequest::Delegate* delegate,
13484 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0313485 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4713486 last_stream_request_ = fake_request->AsWeakPtr();
13487 return fake_request;
13488 }
13489
dchengb03027d2014-10-21 12:00:2013490 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4713491 const HttpRequestInfo& info,
13492 RequestPriority priority,
13493 const SSLConfig& server_ssl_config,
13494 const SSLConfig& proxy_ssl_config,
13495 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4613496 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1313497 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4413498 FakeStreamRequest* fake_request =
13499 new FakeStreamRequest(priority, delegate, create_helper);
13500 last_stream_request_ = fake_request->AsWeakPtr();
13501 return fake_request;
[email protected]bf828982013-08-14 18:01:4713502 }
13503
dchengb03027d2014-10-21 12:00:2013504 void PreconnectStreams(int num_streams,
13505 const HttpRequestInfo& info,
dchengb03027d2014-10-21 12:00:2013506 const SSLConfig& server_ssl_config,
13507 const SSLConfig& proxy_ssl_config) override {
[email protected]bf828982013-08-14 18:01:4713508 ADD_FAILURE();
13509 }
13510
dchengb03027d2014-10-21 12:00:2013511 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4713512 ADD_FAILURE();
13513 return NULL;
13514 }
13515
13516 private:
13517 base::WeakPtr<FakeStreamRequest> last_stream_request_;
13518
13519 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
13520};
13521
Adam Rice425cf122015-01-19 06:18:2413522// TODO(ricea): Maybe unify this with the one in
13523// url_request_http_job_unittest.cc ?
13524class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
13525 public:
13526 FakeWebSocketBasicHandshakeStream(scoped_ptr<ClientSocketHandle> connection,
13527 bool using_proxy)
13528 : state_(connection.release(), using_proxy) {}
13529
13530 // Fake implementation of HttpStreamBase methods.
13531 // This ends up being quite "real" because this object has to really send data
13532 // on the mock socket. It might be easier to use the real implementation, but
13533 // the fact that the WebSocket code is not compiled on iOS makes that
13534 // difficult.
13535 int InitializeStream(const HttpRequestInfo* request_info,
13536 RequestPriority priority,
13537 const BoundNetLog& net_log,
13538 const CompletionCallback& callback) override {
13539 state_.Initialize(request_info, priority, net_log, callback);
13540 return OK;
13541 }
13542
13543 int SendRequest(const HttpRequestHeaders& request_headers,
13544 HttpResponseInfo* response,
13545 const CompletionCallback& callback) override {
13546 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
13547 response, callback);
13548 }
13549
13550 int ReadResponseHeaders(const CompletionCallback& callback) override {
13551 return parser()->ReadResponseHeaders(callback);
13552 }
13553
13554 int ReadResponseBody(IOBuffer* buf,
13555 int buf_len,
13556 const CompletionCallback& callback) override {
13557 NOTREACHED();
13558 return ERR_IO_PENDING;
13559 }
13560
13561 void Close(bool not_reusable) override {
13562 if (parser())
13563 parser()->Close(true);
13564 }
13565
13566 bool IsResponseBodyComplete() const override {
13567 NOTREACHED();
13568 return false;
13569 }
13570
Adam Rice425cf122015-01-19 06:18:2413571 bool IsConnectionReused() const override {
13572 NOTREACHED();
13573 return false;
13574 }
13575 void SetConnectionReused() override { NOTREACHED(); }
13576
mmenkebd84c392015-09-02 14:12:3413577 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2413578
13579 int64 GetTotalReceivedBytes() const override {
13580 NOTREACHED();
13581 return 0;
13582 }
13583
sclittlebe1ccf62015-09-02 19:40:3613584 int64_t GetTotalSentBytes() const override {
13585 NOTREACHED();
13586 return 0;
13587 }
13588
Adam Rice425cf122015-01-19 06:18:2413589 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
13590 NOTREACHED();
13591 return false;
13592 }
13593
Adam Ricecb76ac62015-02-20 05:33:2513594 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2413595
13596 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
13597 NOTREACHED();
13598 }
13599
Adam Rice425cf122015-01-19 06:18:2413600 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
13601
13602 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
13603
13604 UploadProgress GetUploadProgress() const override {
13605 NOTREACHED();
13606 return UploadProgress();
13607 }
13608
13609 HttpStream* RenewStreamForAuth() override {
13610 NOTREACHED();
13611 return nullptr;
13612 }
13613
13614 // Fake implementation of WebSocketHandshakeStreamBase method(s)
13615 scoped_ptr<WebSocketStream> Upgrade() override {
13616 NOTREACHED();
13617 return scoped_ptr<WebSocketStream>();
13618 }
13619
13620 private:
13621 HttpStreamParser* parser() const { return state_.parser(); }
13622 HttpBasicState state_;
13623
13624 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
13625};
13626
[email protected]831e4a32013-11-14 02:14:4413627// TODO(yhirano): Split this class out into a net/websockets file, if it is
13628// worth doing.
13629class FakeWebSocketStreamCreateHelper :
13630 public WebSocketHandshakeStreamBase::CreateHelper {
13631 public:
dchengb03027d2014-10-21 12:00:2013632 WebSocketHandshakeStreamBase* CreateBasicStream(
[email protected]7e841a52013-11-22 09:04:2113633 scoped_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1313634 bool using_proxy) override {
Adam Rice425cf122015-01-19 06:18:2413635 return new FakeWebSocketBasicHandshakeStream(connection.Pass(),
13636 using_proxy);
[email protected]831e4a32013-11-14 02:14:4413637 }
13638
dchengb03027d2014-10-21 12:00:2013639 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4413640 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1313641 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4413642 NOTREACHED();
13643 return NULL;
13644 };
13645
dchengb03027d2014-10-21 12:00:2013646 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4413647
13648 virtual scoped_ptr<WebSocketStream> Upgrade() {
13649 NOTREACHED();
13650 return scoped_ptr<WebSocketStream>();
13651 }
13652};
13653
[email protected]bf828982013-08-14 18:01:4713654} // namespace
13655
13656// Make sure that HttpNetworkTransaction passes on its priority to its
13657// stream request on start.
13658TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
13659 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13660 HttpNetworkSessionPeer peer(session);
13661 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413662 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713663
dcheng48459ac22014-08-26 00:46:4113664 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713665
13666 ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
13667
13668 HttpRequestInfo request;
13669 TestCompletionCallback callback;
13670 EXPECT_EQ(ERR_IO_PENDING,
13671 trans.Start(&request, callback.callback(), BoundNetLog()));
13672
13673 base::WeakPtr<FakeStreamRequest> fake_request =
13674 fake_factory->last_stream_request();
13675 ASSERT_TRUE(fake_request != NULL);
13676 EXPECT_EQ(LOW, fake_request->priority());
13677}
13678
13679// Make sure that HttpNetworkTransaction passes on its priority
13680// updates to its stream request.
13681TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
13682 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13683 HttpNetworkSessionPeer peer(session);
13684 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413685 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4713686
dcheng48459ac22014-08-26 00:46:4113687 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4713688
13689 HttpRequestInfo request;
13690 TestCompletionCallback callback;
13691 EXPECT_EQ(ERR_IO_PENDING,
13692 trans.Start(&request, callback.callback(), BoundNetLog()));
13693
13694 base::WeakPtr<FakeStreamRequest> fake_request =
13695 fake_factory->last_stream_request();
13696 ASSERT_TRUE(fake_request != NULL);
13697 EXPECT_EQ(LOW, fake_request->priority());
13698
13699 trans.SetPriority(LOWEST);
13700 ASSERT_TRUE(fake_request != NULL);
13701 EXPECT_EQ(LOWEST, fake_request->priority());
13702}
13703
[email protected]e86839fd2013-08-14 18:29:0313704// Make sure that HttpNetworkTransaction passes on its priority
13705// updates to its stream.
13706TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
13707 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13708 HttpNetworkSessionPeer peer(session);
13709 FakeStreamFactory* fake_factory = new FakeStreamFactory();
[email protected]831e4a32013-11-14 02:14:4413710 peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0313711
dcheng48459ac22014-08-26 00:46:4113712 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0313713
13714 HttpRequestInfo request;
13715 TestCompletionCallback callback;
13716 EXPECT_EQ(ERR_IO_PENDING,
13717 trans.Start(&request, callback.callback(), BoundNetLog()));
13718
13719 base::WeakPtr<FakeStreamRequest> fake_request =
13720 fake_factory->last_stream_request();
13721 ASSERT_TRUE(fake_request != NULL);
13722 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
13723 ASSERT_TRUE(fake_stream != NULL);
13724 EXPECT_EQ(LOW, fake_stream->priority());
13725
13726 trans.SetPriority(LOWEST);
13727 EXPECT_EQ(LOWEST, fake_stream->priority());
13728}
13729
[email protected]831e4a32013-11-14 02:14:4413730TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
13731 // The same logic needs to be tested for both ws: and wss: schemes, but this
13732 // test is already parameterised on NextProto, so it uses a loop to verify
13733 // that the different schemes work.
bncce36dca22015-04-21 22:11:2313734 std::string test_cases[] = {"ws://www.example.org/",
13735 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4413736 for (size_t i = 0; i < arraysize(test_cases); ++i) {
13737 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13738 HttpNetworkSessionPeer peer(session);
13739 FakeStreamFactory* fake_factory = new FakeStreamFactory();
13740 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2313741 peer.SetHttpStreamFactoryForWebSocket(
[email protected]831e4a32013-11-14 02:14:4413742 scoped_ptr<HttpStreamFactory>(fake_factory));
13743
dcheng48459ac22014-08-26 00:46:4113744 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4413745 trans.SetWebSocketHandshakeStreamCreateHelper(
13746 &websocket_stream_create_helper);
13747
13748 HttpRequestInfo request;
13749 TestCompletionCallback callback;
13750 request.method = "GET";
13751 request.url = GURL(test_cases[i]);
13752
13753 EXPECT_EQ(ERR_IO_PENDING,
13754 trans.Start(&request, callback.callback(), BoundNetLog()));
13755
13756 base::WeakPtr<FakeStreamRequest> fake_request =
13757 fake_factory->last_stream_request();
13758 ASSERT_TRUE(fake_request != NULL);
13759 EXPECT_EQ(&websocket_stream_create_helper,
13760 fake_request->websocket_stream_create_helper());
13761 }
13762}
13763
[email protected]043b68c82013-08-22 23:41:5213764// Tests that when a used socket is returned to the SSL socket pool, it's closed
13765// if the transport socket pool is stalled on the global socket limit.
13766TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
13767 ClientSocketPoolManager::set_max_sockets_per_group(
13768 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13769 ClientSocketPoolManager::set_max_sockets_per_pool(
13770 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13771
13772 // Set up SSL request.
13773
13774 HttpRequestInfo ssl_request;
13775 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2313776 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213777
13778 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2313779 MockWrite(
13780 "GET / HTTP/1.1\r\n"
13781 "Host: www.example.org\r\n"
13782 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213783 };
13784 MockRead ssl_reads[] = {
13785 MockRead("HTTP/1.1 200 OK\r\n"),
13786 MockRead("Content-Length: 11\r\n\r\n"),
13787 MockRead("hello world"),
13788 MockRead(SYNCHRONOUS, OK),
13789 };
13790 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
13791 ssl_writes, arraysize(ssl_writes));
13792 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13793
13794 SSLSocketDataProvider ssl(ASYNC, OK);
13795 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13796
13797 // Set up HTTP request.
13798
13799 HttpRequestInfo http_request;
13800 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313801 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213802
13803 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313804 MockWrite(
13805 "GET / HTTP/1.1\r\n"
13806 "Host: www.example.org\r\n"
13807 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213808 };
13809 MockRead http_reads[] = {
13810 MockRead("HTTP/1.1 200 OK\r\n"),
13811 MockRead("Content-Length: 7\r\n\r\n"),
13812 MockRead("falafel"),
13813 MockRead(SYNCHRONOUS, OK),
13814 };
13815 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13816 http_writes, arraysize(http_writes));
13817 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13818
13819 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13820
13821 // Start the SSL request.
13822 TestCompletionCallback ssl_callback;
13823 scoped_ptr<HttpTransaction> ssl_trans(
13824 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13825 ASSERT_EQ(ERR_IO_PENDING,
13826 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
13827 BoundNetLog()));
13828
13829 // Start the HTTP request. Pool should stall.
13830 TestCompletionCallback http_callback;
13831 scoped_ptr<HttpTransaction> http_trans(
13832 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13833 ASSERT_EQ(ERR_IO_PENDING,
13834 http_trans->Start(&http_request, http_callback.callback(),
13835 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113836 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213837
13838 // Wait for response from SSL request.
13839 ASSERT_EQ(OK, ssl_callback.WaitForResult());
13840 std::string response_data;
13841 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
13842 EXPECT_EQ("hello world", response_data);
13843
13844 // The SSL socket should automatically be closed, so the HTTP request can
13845 // start.
dcheng48459ac22014-08-26 00:46:4113846 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
13847 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213848
13849 // The HTTP request can now complete.
13850 ASSERT_EQ(OK, http_callback.WaitForResult());
13851 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13852 EXPECT_EQ("falafel", response_data);
13853
dcheng48459ac22014-08-26 00:46:4113854 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213855}
13856
13857// Tests that when a SSL connection is established but there's no corresponding
13858// request that needs it, the new socket is closed if the transport socket pool
13859// is stalled on the global socket limit.
13860TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
13861 ClientSocketPoolManager::set_max_sockets_per_group(
13862 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13863 ClientSocketPoolManager::set_max_sockets_per_pool(
13864 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
13865
13866 // Set up an ssl request.
13867
13868 HttpRequestInfo ssl_request;
13869 ssl_request.method = "GET";
13870 ssl_request.url = GURL("https://www.foopy.com/");
13871
13872 // No data will be sent on the SSL socket.
13873 StaticSocketDataProvider ssl_data;
13874 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
13875
13876 SSLSocketDataProvider ssl(ASYNC, OK);
13877 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13878
13879 // Set up HTTP request.
13880
13881 HttpRequestInfo http_request;
13882 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2313883 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5213884
13885 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2313886 MockWrite(
13887 "GET / HTTP/1.1\r\n"
13888 "Host: www.example.org\r\n"
13889 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5213890 };
13891 MockRead http_reads[] = {
13892 MockRead("HTTP/1.1 200 OK\r\n"),
13893 MockRead("Content-Length: 7\r\n\r\n"),
13894 MockRead("falafel"),
13895 MockRead(SYNCHRONOUS, OK),
13896 };
13897 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13898 http_writes, arraysize(http_writes));
13899 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13900
13901 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13902
13903 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
13904 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2913905 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
13906 SSLConfig ssl_config;
[email protected]043b68c82013-08-22 23:41:5213907 session->ssl_config_service()->GetSSLConfig(&ssl_config);
mmenked1205bd2015-07-15 22:26:3513908 http_stream_factory->PreconnectStreams(1, ssl_request, ssl_config,
13909 ssl_config);
dcheng48459ac22014-08-26 00:46:4113910 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213911
13912 // Start the HTTP request. Pool should stall.
13913 TestCompletionCallback http_callback;
13914 scoped_ptr<HttpTransaction> http_trans(
13915 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13916 ASSERT_EQ(ERR_IO_PENDING,
13917 http_trans->Start(&http_request, http_callback.callback(),
13918 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4113919 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5213920
13921 // The SSL connection will automatically be closed once the connection is
13922 // established, to let the HTTP request start.
13923 ASSERT_EQ(OK, http_callback.WaitForResult());
13924 std::string response_data;
13925 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
13926 EXPECT_EQ("falafel", response_data);
13927
dcheng48459ac22014-08-26 00:46:4113928 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5213929}
13930
[email protected]02d74a02014-04-23 18:10:5413931TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
13932 ScopedVector<UploadElementReader> element_readers;
13933 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0713934 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5413935
13936 HttpRequestInfo request;
13937 request.method = "POST";
13938 request.url = GURL("http://www.foo.com/");
13939 request.upload_data_stream = &upload_data_stream;
13940 request.load_flags = 0;
13941
13942 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13943 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4113944 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5413945 // Send headers successfully, but get an error while sending the body.
13946 MockWrite data_writes[] = {
13947 MockWrite("POST / HTTP/1.1\r\n"
13948 "Host: www.foo.com\r\n"
13949 "Connection: keep-alive\r\n"
13950 "Content-Length: 3\r\n\r\n"),
13951 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13952 };
13953
13954 MockRead data_reads[] = {
13955 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
13956 MockRead("hello world"),
13957 MockRead(SYNCHRONOUS, OK),
13958 };
13959 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
13960 arraysize(data_writes));
13961 session_deps_.socket_factory->AddSocketDataProvider(&data);
13962
13963 TestCompletionCallback callback;
13964
13965 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13966 EXPECT_EQ(ERR_IO_PENDING, rv);
13967
13968 rv = callback.WaitForResult();
13969 EXPECT_EQ(OK, rv);
13970
13971 const HttpResponseInfo* response = trans->GetResponseInfo();
13972 ASSERT_TRUE(response != NULL);
13973
13974 EXPECT_TRUE(response->headers.get() != NULL);
13975 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
13976
13977 std::string response_data;
13978 rv = ReadTransaction(trans.get(), &response_data);
13979 EXPECT_EQ(OK, rv);
13980 EXPECT_EQ("hello world", response_data);
13981}
13982
13983// This test makes sure the retry logic doesn't trigger when reading an error
13984// response from a server that rejected a POST with a CONNECTION_RESET.
13985TEST_P(HttpNetworkTransactionTest,
13986 PostReadsErrorResponseAfterResetOnReusedSocket) {
13987 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13988 MockWrite data_writes[] = {
13989 MockWrite("GET / HTTP/1.1\r\n"
13990 "Host: www.foo.com\r\n"
13991 "Connection: keep-alive\r\n\r\n"),
13992 MockWrite("POST / HTTP/1.1\r\n"
13993 "Host: www.foo.com\r\n"
13994 "Connection: keep-alive\r\n"
13995 "Content-Length: 3\r\n\r\n"),
13996 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
13997 };
13998
13999 MockRead data_reads[] = {
14000 MockRead("HTTP/1.1 200 Peachy\r\n"
14001 "Content-Length: 14\r\n\r\n"),
14002 MockRead("first response"),
14003 MockRead("HTTP/1.1 400 Not OK\r\n"
14004 "Content-Length: 15\r\n\r\n"),
14005 MockRead("second response"),
14006 MockRead(SYNCHRONOUS, OK),
14007 };
14008 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14009 arraysize(data_writes));
14010 session_deps_.socket_factory->AddSocketDataProvider(&data);
14011
14012 TestCompletionCallback callback;
14013 HttpRequestInfo request1;
14014 request1.method = "GET";
14015 request1.url = GURL("http://www.foo.com/");
14016 request1.load_flags = 0;
14017
14018 scoped_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4114019 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414020 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
14021 EXPECT_EQ(ERR_IO_PENDING, rv);
14022
14023 rv = callback.WaitForResult();
14024 EXPECT_EQ(OK, rv);
14025
14026 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
14027 ASSERT_TRUE(response1 != NULL);
14028
14029 EXPECT_TRUE(response1->headers.get() != NULL);
14030 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
14031
14032 std::string response_data1;
14033 rv = ReadTransaction(trans1.get(), &response_data1);
14034 EXPECT_EQ(OK, rv);
14035 EXPECT_EQ("first response", response_data1);
14036 // Delete the transaction to release the socket back into the socket pool.
14037 trans1.reset();
14038
14039 ScopedVector<UploadElementReader> element_readers;
14040 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714041 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414042
14043 HttpRequestInfo request2;
14044 request2.method = "POST";
14045 request2.url = GURL("http://www.foo.com/");
14046 request2.upload_data_stream = &upload_data_stream;
14047 request2.load_flags = 0;
14048
14049 scoped_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4114050 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414051 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
14052 EXPECT_EQ(ERR_IO_PENDING, rv);
14053
14054 rv = callback.WaitForResult();
14055 EXPECT_EQ(OK, rv);
14056
14057 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
14058 ASSERT_TRUE(response2 != NULL);
14059
14060 EXPECT_TRUE(response2->headers.get() != NULL);
14061 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
14062
14063 std::string response_data2;
14064 rv = ReadTransaction(trans2.get(), &response_data2);
14065 EXPECT_EQ(OK, rv);
14066 EXPECT_EQ("second response", response_data2);
14067}
14068
14069TEST_P(HttpNetworkTransactionTest,
14070 PostReadsErrorResponseAfterResetPartialBodySent) {
14071 ScopedVector<UploadElementReader> element_readers;
14072 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714073 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414074
14075 HttpRequestInfo request;
14076 request.method = "POST";
14077 request.url = GURL("http://www.foo.com/");
14078 request.upload_data_stream = &upload_data_stream;
14079 request.load_flags = 0;
14080
14081 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14082 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114083 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414084 // Send headers successfully, but get an error while sending the body.
14085 MockWrite data_writes[] = {
14086 MockWrite("POST / HTTP/1.1\r\n"
14087 "Host: www.foo.com\r\n"
14088 "Connection: keep-alive\r\n"
14089 "Content-Length: 3\r\n\r\n"
14090 "fo"),
14091 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14092 };
14093
14094 MockRead data_reads[] = {
14095 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14096 MockRead("hello world"),
14097 MockRead(SYNCHRONOUS, OK),
14098 };
14099 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14100 arraysize(data_writes));
14101 session_deps_.socket_factory->AddSocketDataProvider(&data);
14102
14103 TestCompletionCallback callback;
14104
14105 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14106 EXPECT_EQ(ERR_IO_PENDING, rv);
14107
14108 rv = callback.WaitForResult();
14109 EXPECT_EQ(OK, rv);
14110
14111 const HttpResponseInfo* response = trans->GetResponseInfo();
14112 ASSERT_TRUE(response != NULL);
14113
14114 EXPECT_TRUE(response->headers.get() != NULL);
14115 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14116
14117 std::string response_data;
14118 rv = ReadTransaction(trans.get(), &response_data);
14119 EXPECT_EQ(OK, rv);
14120 EXPECT_EQ("hello world", response_data);
14121}
14122
14123// This tests the more common case than the previous test, where headers and
14124// body are not merged into a single request.
14125TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
14126 ScopedVector<UploadElementReader> element_readers;
14127 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714128 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5414129
14130 HttpRequestInfo request;
14131 request.method = "POST";
14132 request.url = GURL("http://www.foo.com/");
14133 request.upload_data_stream = &upload_data_stream;
14134 request.load_flags = 0;
14135
14136 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14137 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114138 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414139 // Send headers successfully, but get an error while sending the body.
14140 MockWrite data_writes[] = {
14141 MockWrite("POST / HTTP/1.1\r\n"
14142 "Host: www.foo.com\r\n"
14143 "Connection: keep-alive\r\n"
14144 "Transfer-Encoding: chunked\r\n\r\n"),
14145 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14146 };
14147
14148 MockRead data_reads[] = {
14149 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14150 MockRead("hello world"),
14151 MockRead(SYNCHRONOUS, OK),
14152 };
14153 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14154 arraysize(data_writes));
14155 session_deps_.socket_factory->AddSocketDataProvider(&data);
14156
14157 TestCompletionCallback callback;
14158
14159 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14160 EXPECT_EQ(ERR_IO_PENDING, rv);
14161 // Make sure the headers are sent before adding a chunk. This ensures that
14162 // they can't be merged with the body in a single send. Not currently
14163 // necessary since a chunked body is never merged with headers, but this makes
14164 // the test more future proof.
14165 base::RunLoop().RunUntilIdle();
14166
mmenkecbc2b712014-10-09 20:29:0714167 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5414168
14169 rv = callback.WaitForResult();
14170 EXPECT_EQ(OK, rv);
14171
14172 const HttpResponseInfo* response = trans->GetResponseInfo();
14173 ASSERT_TRUE(response != NULL);
14174
14175 EXPECT_TRUE(response->headers.get() != NULL);
14176 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14177
14178 std::string response_data;
14179 rv = ReadTransaction(trans.get(), &response_data);
14180 EXPECT_EQ(OK, rv);
14181 EXPECT_EQ("hello world", response_data);
14182}
14183
14184TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
14185 ScopedVector<UploadElementReader> element_readers;
14186 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714187 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414188
14189 HttpRequestInfo request;
14190 request.method = "POST";
14191 request.url = GURL("http://www.foo.com/");
14192 request.upload_data_stream = &upload_data_stream;
14193 request.load_flags = 0;
14194
14195 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14196 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114197 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414198
14199 MockWrite data_writes[] = {
14200 MockWrite("POST / HTTP/1.1\r\n"
14201 "Host: www.foo.com\r\n"
14202 "Connection: keep-alive\r\n"
14203 "Content-Length: 3\r\n\r\n"),
14204 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14205 };
14206
14207 MockRead data_reads[] = {
14208 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
14209 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
14210 MockRead("hello world"),
14211 MockRead(SYNCHRONOUS, OK),
14212 };
14213 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14214 arraysize(data_writes));
14215 session_deps_.socket_factory->AddSocketDataProvider(&data);
14216
14217 TestCompletionCallback callback;
14218
14219 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14220 EXPECT_EQ(ERR_IO_PENDING, rv);
14221
14222 rv = callback.WaitForResult();
14223 EXPECT_EQ(OK, rv);
14224
14225 const HttpResponseInfo* response = trans->GetResponseInfo();
14226 ASSERT_TRUE(response != NULL);
14227
14228 EXPECT_TRUE(response->headers.get() != NULL);
14229 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
14230
14231 std::string response_data;
14232 rv = ReadTransaction(trans.get(), &response_data);
14233 EXPECT_EQ(OK, rv);
14234 EXPECT_EQ("hello world", response_data);
14235}
14236
14237TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
14238 ScopedVector<UploadElementReader> element_readers;
14239 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714240 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414241
14242 HttpRequestInfo request;
14243 request.method = "POST";
14244 request.url = GURL("http://www.foo.com/");
14245 request.upload_data_stream = &upload_data_stream;
14246 request.load_flags = 0;
14247
14248 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14249 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114250 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414251 // Send headers successfully, but get an error while sending the body.
14252 MockWrite data_writes[] = {
14253 MockWrite("POST / HTTP/1.1\r\n"
14254 "Host: www.foo.com\r\n"
14255 "Connection: keep-alive\r\n"
14256 "Content-Length: 3\r\n\r\n"),
14257 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14258 };
14259
14260 MockRead data_reads[] = {
14261 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
14262 MockRead("hello world"),
14263 MockRead(SYNCHRONOUS, OK),
14264 };
14265 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14266 arraysize(data_writes));
14267 session_deps_.socket_factory->AddSocketDataProvider(&data);
14268
14269 TestCompletionCallback callback;
14270
14271 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14272 EXPECT_EQ(ERR_IO_PENDING, rv);
14273
14274 rv = callback.WaitForResult();
14275 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414276}
14277
14278TEST_P(HttpNetworkTransactionTest,
14279 PostIgnoresNonErrorResponseAfterResetAnd100) {
14280 ScopedVector<UploadElementReader> element_readers;
14281 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714282 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414283
14284 HttpRequestInfo request;
14285 request.method = "POST";
14286 request.url = GURL("http://www.foo.com/");
14287 request.upload_data_stream = &upload_data_stream;
14288 request.load_flags = 0;
14289
14290 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14291 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114292 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414293 // Send headers successfully, but get an error while sending the body.
14294 MockWrite data_writes[] = {
14295 MockWrite("POST / HTTP/1.1\r\n"
14296 "Host: www.foo.com\r\n"
14297 "Connection: keep-alive\r\n"
14298 "Content-Length: 3\r\n\r\n"),
14299 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14300 };
14301
14302 MockRead data_reads[] = {
14303 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
14304 MockRead("HTTP/1.0 302 Redirect\r\n"),
14305 MockRead("Location: http://somewhere-else.com/\r\n"),
14306 MockRead("Content-Length: 0\r\n\r\n"),
14307 MockRead(SYNCHRONOUS, OK),
14308 };
14309 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14310 arraysize(data_writes));
14311 session_deps_.socket_factory->AddSocketDataProvider(&data);
14312
14313 TestCompletionCallback callback;
14314
14315 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14316 EXPECT_EQ(ERR_IO_PENDING, rv);
14317
14318 rv = callback.WaitForResult();
14319 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414320}
14321
14322TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
14323 ScopedVector<UploadElementReader> element_readers;
14324 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714325 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414326
14327 HttpRequestInfo request;
14328 request.method = "POST";
14329 request.url = GURL("http://www.foo.com/");
14330 request.upload_data_stream = &upload_data_stream;
14331 request.load_flags = 0;
14332
14333 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14334 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114335 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414336 // Send headers successfully, but get an error while sending the body.
14337 MockWrite data_writes[] = {
14338 MockWrite("POST / HTTP/1.1\r\n"
14339 "Host: www.foo.com\r\n"
14340 "Connection: keep-alive\r\n"
14341 "Content-Length: 3\r\n\r\n"),
14342 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14343 };
14344
14345 MockRead data_reads[] = {
14346 MockRead("HTTP 0.9 rocks!"),
14347 MockRead(SYNCHRONOUS, OK),
14348 };
14349 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14350 arraysize(data_writes));
14351 session_deps_.socket_factory->AddSocketDataProvider(&data);
14352
14353 TestCompletionCallback callback;
14354
14355 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14356 EXPECT_EQ(ERR_IO_PENDING, rv);
14357
14358 rv = callback.WaitForResult();
14359 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414360}
14361
14362TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
14363 ScopedVector<UploadElementReader> element_readers;
14364 element_readers.push_back(new UploadBytesElementReader("foo", 3));
mmenkecbc2b712014-10-09 20:29:0714365 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
[email protected]02d74a02014-04-23 18:10:5414366
14367 HttpRequestInfo request;
14368 request.method = "POST";
14369 request.url = GURL("http://www.foo.com/");
14370 request.upload_data_stream = &upload_data_stream;
14371 request.load_flags = 0;
14372
14373 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14374 scoped_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114375 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5414376 // Send headers successfully, but get an error while sending the body.
14377 MockWrite data_writes[] = {
14378 MockWrite("POST / HTTP/1.1\r\n"
14379 "Host: www.foo.com\r\n"
14380 "Connection: keep-alive\r\n"
14381 "Content-Length: 3\r\n\r\n"),
14382 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14383 };
14384
14385 MockRead data_reads[] = {
14386 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
14387 MockRead(SYNCHRONOUS, OK),
14388 };
14389 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14390 arraysize(data_writes));
14391 session_deps_.socket_factory->AddSocketDataProvider(&data);
14392
14393 TestCompletionCallback callback;
14394
14395 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14396 EXPECT_EQ(ERR_IO_PENDING, rv);
14397
14398 rv = callback.WaitForResult();
14399 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5414400}
14401
Adam Rice425cf122015-01-19 06:18:2414402// Verify that proxy headers are not sent to the destination server when
14403// establishing a tunnel for a secure WebSocket connection.
14404TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
14405 HttpRequestInfo request;
14406 request.method = "GET";
bncce36dca22015-04-21 22:11:2314407 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414408 AddWebSocketHeaders(&request.extra_headers);
14409
14410 // Configure against proxy server "myproxy:70".
14411 session_deps_.proxy_service.reset(
14412 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
14413
14414 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14415
14416 // Since a proxy is configured, try to establish a tunnel.
14417 MockWrite data_writes[] = {
14418 MockWrite(
bncce36dca22015-04-21 22:11:2314419 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14420 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414421 "Proxy-Connection: keep-alive\r\n\r\n"),
14422
14423 // After calling trans->RestartWithAuth(), this is the request we should
14424 // be issuing -- the final header line contains the credentials.
14425 MockWrite(
bncce36dca22015-04-21 22:11:2314426 "CONNECT www.example.org:443 HTTP/1.1\r\n"
14427 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414428 "Proxy-Connection: keep-alive\r\n"
14429 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14430
14431 MockWrite(
14432 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314433 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414434 "Connection: Upgrade\r\n"
14435 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314436 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414437 "Sec-WebSocket-Version: 13\r\n"
14438 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14439 };
14440
14441 // The proxy responds to the connect with a 407, using a persistent
14442 // connection.
14443 MockRead data_reads[] = {
14444 // No credentials.
14445 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
14446 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee0b5c882015-08-26 20:29:1114447 MockRead("Content-Length: 0\r\n"),
14448 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2414449
14450 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14451
14452 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14453 MockRead("Upgrade: websocket\r\n"),
14454 MockRead("Connection: Upgrade\r\n"),
14455 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14456 };
14457
14458 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14459 arraysize(data_writes));
14460 session_deps_.socket_factory->AddSocketDataProvider(&data);
14461 SSLSocketDataProvider ssl(ASYNC, OK);
14462 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14463
14464 scoped_ptr<HttpTransaction> trans(
14465 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14466 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14467 trans->SetWebSocketHandshakeStreamCreateHelper(
14468 &websocket_stream_create_helper);
14469
14470 {
14471 TestCompletionCallback callback;
14472
14473 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14474 EXPECT_EQ(ERR_IO_PENDING, rv);
14475
14476 rv = callback.WaitForResult();
14477 EXPECT_EQ(OK, rv);
14478 }
14479
14480 const HttpResponseInfo* response = trans->GetResponseInfo();
14481 ASSERT_TRUE(response);
14482 ASSERT_TRUE(response->headers.get());
14483 EXPECT_EQ(407, response->headers->response_code());
14484
14485 {
14486 TestCompletionCallback callback;
14487
14488 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
14489 callback.callback());
14490 EXPECT_EQ(ERR_IO_PENDING, rv);
14491
14492 rv = callback.WaitForResult();
14493 EXPECT_EQ(OK, rv);
14494 }
14495
14496 response = trans->GetResponseInfo();
14497 ASSERT_TRUE(response);
14498 ASSERT_TRUE(response->headers.get());
14499
14500 EXPECT_EQ(101, response->headers->response_code());
14501
14502 trans.reset();
14503 session->CloseAllConnections();
14504}
14505
14506// Verify that proxy headers are not sent to the destination server when
14507// establishing a tunnel for an insecure WebSocket connection.
14508// This requires the authentication info to be injected into the auth cache
14509// due to crbug.com/395064
14510// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
14511TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
14512 HttpRequestInfo request;
14513 request.method = "GET";
bncce36dca22015-04-21 22:11:2314514 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2414515 AddWebSocketHeaders(&request.extra_headers);
14516
14517 // Configure against proxy server "myproxy:70".
14518 session_deps_.proxy_service.reset(
14519 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
14520
14521 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14522
14523 MockWrite data_writes[] = {
14524 // Try to establish a tunnel for the WebSocket connection, with
14525 // credentials. Because WebSockets have a separate set of socket pools,
14526 // they cannot and will not use the same TCP/IP connection as the
14527 // preflight HTTP request.
14528 MockWrite(
bncce36dca22015-04-21 22:11:2314529 "CONNECT www.example.org:80 HTTP/1.1\r\n"
14530 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2414531 "Proxy-Connection: keep-alive\r\n"
14532 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
14533
14534 MockWrite(
14535 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2314536 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414537 "Connection: Upgrade\r\n"
14538 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2314539 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2414540 "Sec-WebSocket-Version: 13\r\n"
14541 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
14542 };
14543
14544 MockRead data_reads[] = {
14545 // HTTP CONNECT with credentials.
14546 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14547
14548 // WebSocket connection established inside tunnel.
14549 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
14550 MockRead("Upgrade: websocket\r\n"),
14551 MockRead("Connection: Upgrade\r\n"),
14552 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
14553 };
14554
14555 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
14556 arraysize(data_writes));
14557 session_deps_.socket_factory->AddSocketDataProvider(&data);
14558
14559 session->http_auth_cache()->Add(
14560 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
14561 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
14562
14563 scoped_ptr<HttpTransaction> trans(
14564 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
14565 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
14566 trans->SetWebSocketHandshakeStreamCreateHelper(
14567 &websocket_stream_create_helper);
14568
14569 TestCompletionCallback callback;
14570
14571 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14572 EXPECT_EQ(ERR_IO_PENDING, rv);
14573
14574 rv = callback.WaitForResult();
14575 EXPECT_EQ(OK, rv);
14576
14577 const HttpResponseInfo* response = trans->GetResponseInfo();
14578 ASSERT_TRUE(response);
14579 ASSERT_TRUE(response->headers.get());
14580
14581 EXPECT_EQ(101, response->headers->response_code());
14582
14583 trans.reset();
14584 session->CloseAllConnections();
14585}
14586
[email protected]89ceba9a2009-03-21 03:46:0614587} // namespace net