blob: 532cdd5d261096f3d110bd6ee9c0668322fc5a9f [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>
danakj1fd259a02016-04-16 03:17:0910
avibf0746c2015-12-09 19:53:1411#include <limits>
danakj1fd259a02016-04-16 03:17:0912#include <memory>
[email protected]5285d972011-10-18 18:56:3413#include <string>
dchengc7eeda422015-12-26 03:56:4814#include <utility>
[email protected]95d88ffe2010-02-04 21:25:3315#include <vector>
[email protected]77848d12008-11-14 00:00:2216
[email protected]68bf9152008-09-25 19:47:3017#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5218#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2919#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5720#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2421#include "base/logging.h"
Avi Drissman13fc8932015-12-20 04:40:4622#include "base/macros.h"
danakj1fd259a02016-04-16 03:17:0923#include "base/memory/ptr_util.h"
[email protected]bf828982013-08-14 18:01:4724#include "base/memory/weak_ptr.h"
[email protected]a34f61ee2014-03-18 20:59:4925#include "base/run_loop.h"
[email protected]125ef482013-06-11 18:32:4726#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0527#include "base/strings/utf_string_conversions.h"
[email protected]f36a8132011-09-02 18:36:3328#include "base/test/test_file_util.h"
gabf767595f2016-05-11 18:50:3529#include "base/threading/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3530#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0731#include "net/base/chunked_upload_data_stream.h"
[email protected]bacff652009-03-31 17:50:3332#include "net/base/completion_callback.h"
mmenkecbc2b712014-10-09 20:29:0733#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2534#include "net/base/load_timing_info.h"
35#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2436#include "net/base/net_errors.h"
tbansal28e68f82016-02-04 02:56:1537#include "net/base/proxy_delegate.h"
[email protected]ac790b42009-12-02 04:31:3138#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5239#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1540#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0641#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2142#include "net/base/upload_file_element_reader.h"
[email protected]6e7845ae2013-03-29 21:48:1143#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1644#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5345#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2446#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1247#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0048#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2949#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1950#include "net/http/http_auth_scheme.h"
Adam Rice425cf122015-01-19 06:18:2451#include "net/http/http_basic_state.h"
[email protected]0877e3d2009-10-17 22:29:5752#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5253#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5654#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2455#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1356#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5357#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5758#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3859#include "net/http/http_stream_factory.h"
Adam Rice425cf122015-01-19 06:18:2460#include "net/http/http_stream_parser.h"
[email protected]c41737d2014-05-14 07:47:1961#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0762#include "net/log/net_log.h"
vishal.b62985ca92015-04-17 08:45:5163#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4664#include "net/log/test_net_log_entry.h"
65#include "net/log/test_net_log_util.h"
sammc5dd160c2015-04-02 02:43:1366#include "net/proxy/mock_proxy_resolver.h"
[email protected]51fff29d2008-12-19 22:17:5367#include "net/proxy/proxy_config_service_fixed.h"
[email protected]e86839fd2013-08-14 18:29:0368#include "net/proxy/proxy_info.h"
[email protected]631f1322010-04-30 17:59:1169#include "net/proxy/proxy_resolver.h"
tbansal28e68f82016-02-04 02:56:1570#include "net/proxy/proxy_server.h"
[email protected]631f1322010-04-30 17:59:1171#include "net/proxy/proxy_service.h"
[email protected]f7984fc62009-06-22 23:26:4472#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1573#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0374#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4775#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0276#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0777#include "net/socket/next_proto.h"
[email protected]f7984fc62009-06-22 23:26:4478#include "net/socket/socket_test_util.h"
79#include "net/socket/ssl_client_socket.h"
[email protected]2ff8b312010-04-26 22:20:5480#include "net/spdy/spdy_framer.h"
81#include "net/spdy/spdy_session.h"
82#include "net/spdy/spdy_session_pool.h"
[email protected]23e482282013-06-14 16:08:0283#include "net/spdy/spdy_test_util_common.h"
nharperb7441ef2016-01-25 23:54:1484#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5785#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0386#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5787#include "net/ssl/ssl_config_service_defaults.h"
88#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5489#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1190#include "net/test/cert_test_util.h"
rsleevia69c79a2016-06-22 03:28:4391#include "net/test/test_data_directory.h"
[email protected]831e4a32013-11-14 02:14:4492#include "net/websockets/websocket_handshake_stream_base.h"
bncf4588402015-11-24 13:33:1893#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:5294#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1595#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:2796#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:5297
[email protected]ad65a3e2013-12-25 18:18:0198using base::ASCIIToUTF16;
99
initial.commit586acc5fe2008-07-26 22:42:52100//-----------------------------------------------------------------------------
101
ttuttle859dc7a2015-04-23 19:42:29102namespace net {
103
[email protected]13c8a092010-07-29 06:15:44104namespace {
105
rdsmithebb50aa2015-11-12 03:44:38106enum TestCase {
107 // Test using the SPDY/3.1 protocol.
108 kTestCaseSPDY31,
109
110 // Test using the HTTP/2 protocol, without specifying a stream
111 // dependency based on the RequestPriority.
112 kTestCaseHTTP2NoPriorityDependencies,
113
114 // Test using the HTTP/2 protocol, specifying a stream
115 // dependency based on the RequestPriority.
116 kTestCaseHTTP2PriorityDependencies
117};
118
[email protected]42cba2fb2013-03-29 19:58:57119const base::string16 kBar(ASCIIToUTF16("bar"));
120const base::string16 kBar2(ASCIIToUTF16("bar2"));
121const base::string16 kBar3(ASCIIToUTF16("bar3"));
122const base::string16 kBaz(ASCIIToUTF16("baz"));
123const base::string16 kFirst(ASCIIToUTF16("first"));
124const base::string16 kFoo(ASCIIToUTF16("foo"));
125const base::string16 kFoo2(ASCIIToUTF16("foo2"));
126const base::string16 kFoo3(ASCIIToUTF16("foo3"));
127const base::string16 kFou(ASCIIToUTF16("fou"));
128const base::string16 kSecond(ASCIIToUTF16("second"));
129const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
130const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44131
ttuttle859dc7a2015-04-23 19:42:29132int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
133 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
134 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02135}
136
ttuttle859dc7a2015-04-23 19:42:29137int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
138 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
139 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02140}
141
ttuttle859dc7a2015-04-23 19:42:29142bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
143 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
144 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52145}
146
[email protected]f3da152d2012-06-02 01:00:57147// Takes in a Value created from a NetLogHttpResponseParameter, and returns
148// a JSONified list of headers as a single string. Uses single quotes instead
149// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27150bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57151 if (!params)
152 return false;
[email protected]ea5ef4c2013-06-13 22:50:27153 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57154 if (!params->GetList("headers", &header_list))
155 return false;
156 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34157 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28158 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57159 return true;
160}
161
[email protected]029c83b62013-01-24 05:28:20162// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
163// used.
ttuttle859dc7a2015-04-23 19:42:29164void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20165 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29166 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25167
[email protected]029c83b62013-01-24 05:28:20168 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
169 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
170
ttuttle859dc7a2015-04-23 19:42:29171 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20172 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25173
174 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25175
[email protected]3b23a222013-05-15 21:33:25176 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25177 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
178 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25179 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25180}
181
[email protected]029c83b62013-01-24 05:28:20182// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
183// used.
ttuttle859dc7a2015-04-23 19:42:29184void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25185 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20186 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29187 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20188
189 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
190 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
191
ttuttle859dc7a2015-04-23 19:42:29192 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
193 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20194 EXPECT_LE(load_timing_info.connect_timing.connect_end,
195 load_timing_info.send_start);
196
197 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20198
[email protected]3b23a222013-05-15 21:33:25199 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20200 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
201 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25202 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20203}
204
205// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
206// used.
ttuttle859dc7a2015-04-23 19:42:29207void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20208 EXPECT_TRUE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29209 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20210
ttuttle859dc7a2015-04-23 19:42:29211 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20212
213 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
214 EXPECT_LE(load_timing_info.proxy_resolve_start,
215 load_timing_info.proxy_resolve_end);
216 EXPECT_LE(load_timing_info.proxy_resolve_end,
217 load_timing_info.send_start);
218 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20219
[email protected]3b23a222013-05-15 21:33:25220 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20221 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
222 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25223 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20224}
225
226// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
227// used.
ttuttle859dc7a2015-04-23 19:42:29228void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20229 int connect_timing_flags) {
230 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:29231 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20232
233 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
234 EXPECT_LE(load_timing_info.proxy_resolve_start,
235 load_timing_info.proxy_resolve_end);
236 EXPECT_LE(load_timing_info.proxy_resolve_end,
237 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29238 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
239 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20240 EXPECT_LE(load_timing_info.connect_timing.connect_end,
241 load_timing_info.send_start);
242
243 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20244
[email protected]3b23a222013-05-15 21:33:25245 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20246 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
247 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25248 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25249}
250
ttuttle859dc7a2015-04-23 19:42:29251void AddWebSocketHeaders(HttpRequestHeaders* headers) {
Adam Rice425cf122015-01-19 06:18:24252 headers->SetHeader("Connection", "Upgrade");
253 headers->SetHeader("Upgrade", "websocket");
bncce36dca22015-04-21 22:11:23254 headers->SetHeader("Origin", "http://www.example.org");
Adam Rice425cf122015-01-19 06:18:24255 headers->SetHeader("Sec-WebSocket-Version", "13");
256 headers->SetHeader("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
257}
258
danakj1fd259a02016-04-16 03:17:09259std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42260 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34261 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14262}
263
[email protected]448d4ca52012-03-04 04:12:23264} // namespace
265
[email protected]23e482282013-06-14 16:08:02266class HttpNetworkTransactionTest
267 : public PlatformTest,
rdsmithebb50aa2015-11-12 03:44:38268 public ::testing::WithParamInterface<TestCase> {
[email protected]483fa202013-05-14 01:07:03269 public:
[email protected]23e482282013-06-14 16:08:02270 virtual ~HttpNetworkTransactionTest() {
[email protected]483fa202013-05-14 01:07:03271 // Important to restore the per-pool limit first, since the pool limit must
272 // always be greater than group limit, and the tests reduce both limits.
273 ClientSocketPoolManager::set_max_sockets_per_pool(
274 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
275 ClientSocketPoolManager::set_max_sockets_per_group(
276 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
277 }
278
[email protected]e3ceb682011-06-28 23:55:46279 protected:
[email protected]23e482282013-06-14 16:08:02280 HttpNetworkTransactionTest()
rdsmithebb50aa2015-11-12 03:44:38281 : spdy_util_(GetProtocol(), GetDependenciesFromPriority()),
282 session_deps_(GetProtocol()),
[email protected]483fa202013-05-14 01:07:03283 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
284 HttpNetworkSession::NORMAL_SOCKET_POOL)),
285 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
286 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
rdsmith2e54d1f2016-03-21 19:48:17287 session_deps_.enable_priority_dependencies = GetDependenciesFromPriority();
[email protected]483fa202013-05-14 01:07:03288 }
[email protected]bb88e1d32013-05-03 23:11:07289
[email protected]e3ceb682011-06-28 23:55:46290 struct SimpleGetHelperResult {
291 int rv;
292 std::string status_line;
293 std::string response_data;
sclittlefb249892015-09-10 21:33:22294 int64_t total_received_bytes;
295 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25296 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47297 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59298 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46299 };
300
dcheng67be2b1f2014-10-27 21:47:29301 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50302 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55303 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54304 }
305
dcheng67be2b1f2014-10-27 21:47:29306 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50307 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55308 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09309 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55310 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09311 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50312 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55313 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09314 }
315
rdsmithebb50aa2015-11-12 03:44:38316 NextProto GetProtocol() const {
317 return GetParam() == kTestCaseSPDY31 ? kProtoSPDY31 : kProtoHTTP2;
318 }
319
320 bool GetDependenciesFromPriority() const {
321 return GetParam() == kTestCaseHTTP2PriorityDependencies;
322 }
323
bnc33b8cef42014-11-19 17:30:38324 const char* GetAlternateProtocolFromParam() {
rdsmithebb50aa2015-11-12 03:44:38325 return AlternateProtocolToString(
326 AlternateProtocolFromNextProto(GetProtocol()));
bnc33b8cef42014-11-19 17:30:38327 }
328
bncc958faa2015-07-31 18:14:52329 std::string GetAlternativeServiceHttpHeader() {
330 return std::string("Alt-Svc: ") + GetAlternateProtocolFromParam() +
bnc8bef8da22016-05-30 01:28:25331 "=\"www.example.org:443\"\r\n";
bncc958faa2015-07-31 18:14:52332 }
333
[email protected]202965992011-12-07 23:04:51334 // Either |write_failure| specifies a write failure or |read_failure|
335 // specifies a read failure when using a reused socket. In either case, the
336 // failure should cause the network transaction to resend the request, and the
337 // other argument should be NULL.
338 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
339 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52340
[email protected]a34f61ee2014-03-18 20:59:49341 // Either |write_failure| specifies a write failure or |read_failure|
342 // specifies a read failure when using a reused socket. In either case, the
343 // failure should cause the network transaction to resend the request, and the
344 // other argument should be NULL.
345 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10346 const MockRead* read_failure,
347 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49348
[email protected]5a60c8b2011-10-19 20:14:29349 SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
350 size_t data_count) {
[email protected]ff007e162009-05-23 09:13:15351 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52352
[email protected]ff007e162009-05-23 09:13:15353 HttpRequestInfo request;
354 request.method = "GET";
bncce36dca22015-04-21 22:11:23355 request.url = GURL("http://www.example.org/");
[email protected]ff007e162009-05-23 09:13:15356 request.load_flags = 0;
initial.commit586acc5fe2008-07-26 22:42:52357
vishal.b62985ca92015-04-17 08:45:51358 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07359 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09360 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
361 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41362 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:27363
[email protected]5a60c8b2011-10-19 20:14:29364 for (size_t i = 0; i < data_count; ++i) {
[email protected]bb88e1d32013-05-03 23:11:07365 session_deps_.socket_factory->AddSocketDataProvider(data[i]);
[email protected]5a60c8b2011-10-19 20:14:29366 }
initial.commit586acc5fe2008-07-26 22:42:52367
[email protected]49639fa2011-12-20 23:22:41368 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52369
eroman24bc6a12015-05-06 19:55:48370 EXPECT_TRUE(log.bound().IsCapturing());
[email protected]49639fa2011-12-20 23:22:41371 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]ff007e162009-05-23 09:13:15372 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:52373
[email protected]ff007e162009-05-23 09:13:15374 out.rv = callback.WaitForResult();
sclittlefb249892015-09-10 21:33:22375 out.total_received_bytes = trans->GetTotalReceivedBytes();
376 out.total_sent_bytes = trans->GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25377
378 // Even in the failure cases that use this function, connections are always
379 // successfully established before the error.
380 EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
381 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
382
[email protected]ff007e162009-05-23 09:13:15383 if (out.rv != OK)
384 return out;
385
386 const HttpResponseInfo* response = trans->GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50387 // Can't use ASSERT_* inside helper functions like this, so
388 // return an error.
wezca1070932016-05-26 20:30:52389 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50390 out.rv = ERR_UNEXPECTED;
391 return out;
392 }
[email protected]ff007e162009-05-23 09:13:15393 out.status_line = response->headers->GetStatusLine();
394
[email protected]80a09a82012-11-16 17:40:06395 EXPECT_EQ("127.0.0.1", response->socket_address.host());
396 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19397
ttuttled9dbc652015-09-29 20:00:59398 bool got_endpoint =
399 trans->GetRemoteEndpoint(&out.remote_endpoint_after_start);
400 EXPECT_EQ(got_endpoint,
401 out.remote_endpoint_after_start.address().size() > 0);
402
[email protected]ff007e162009-05-23 09:13:15403 rv = ReadTransaction(trans.get(), &out.response_data);
404 EXPECT_EQ(OK, rv);
[email protected]b2fcd0e2010-12-01 15:19:40405
mmenke43758e62015-05-04 21:09:46406 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40407 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39408 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40409 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
[email protected]169d0012010-05-10 23:20:12410 NetLog::PHASE_NONE);
[email protected]dbb83db2010-05-11 18:13:39411 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:40412 entries, pos,
[email protected]dbb83db2010-05-11 18:13:39413 NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
414 NetLog::PHASE_NONE);
[email protected]ff007e162009-05-23 09:13:15415
[email protected]f3da152d2012-06-02 01:00:57416 std::string line;
417 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
418 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
419
[email protected]79e1fd62013-06-20 06:50:04420 HttpRequestHeaders request_headers;
421 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
422 std::string value;
423 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23424 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04425 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
426 EXPECT_EQ("keep-alive", value);
427
428 std::string response_headers;
429 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23430 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04431 response_headers);
[email protected]3deb9a52010-11-11 00:24:40432
sclittlefb249892015-09-10 21:33:22433 out.total_received_bytes = trans->GetTotalReceivedBytes();
434 // The total number of sent bytes should not have changed.
435 EXPECT_EQ(out.total_sent_bytes, trans->GetTotalSentBytes());
436
ttuttle1f2d7e92015-04-28 16:17:47437 trans->GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47438 return out;
[email protected]ff007e162009-05-23 09:13:15439 }
initial.commit586acc5fe2008-07-26 22:42:52440
[email protected]5a60c8b2011-10-19 20:14:29441 SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
442 size_t reads_count) {
sclittlefb249892015-09-10 21:33:22443 MockWrite data_writes[] = {
444 MockWrite("GET / HTTP/1.1\r\n"
445 "Host: www.example.org\r\n"
446 "Connection: keep-alive\r\n\r\n"),
447 };
[email protected]5a60c8b2011-10-19 20:14:29448
sclittlefb249892015-09-10 21:33:22449 StaticSocketDataProvider reads(data_reads, reads_count, data_writes,
450 arraysize(data_writes));
451 StaticSocketDataProvider* data[] = {&reads};
452 SimpleGetHelperResult out = SimpleGetHelperForData(data, 1);
453
454 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
455 out.total_sent_bytes);
456 return out;
[email protected]b8015c42013-12-24 15:18:19457 }
458
[email protected]ff007e162009-05-23 09:13:15459 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
460 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52461
[email protected]ff007e162009-05-23 09:13:15462 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07463
464 void BypassHostCacheOnRefreshHelper(int load_flags);
465
466 void CheckErrorIsPassedBack(int error, IoMode mode);
467
[email protected]4bd46222013-05-14 19:32:23468 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07469 SpdySessionDependencies session_deps_;
[email protected]483fa202013-05-14 01:07:03470
471 // Original socket limits. Some tests set these. Safest to always restore
472 // them once each test has been run.
473 int old_max_group_sockets_;
474 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15475};
[email protected]231d5a32008-09-13 00:45:27476
rdsmithebb50aa2015-11-12 03:44:38477INSTANTIATE_TEST_CASE_P(ProtoPlusDepend,
bnc57685ae62015-03-10 21:27:20478 HttpNetworkTransactionTest,
rdsmithebb50aa2015-11-12 03:44:38479 testing::Values(kTestCaseSPDY31,
480 kTestCaseHTTP2NoPriorityDependencies,
481 kTestCaseHTTP2PriorityDependencies));
[email protected]23e482282013-06-14 16:08:02482
[email protected]448d4ca52012-03-04 04:12:23483namespace {
484
[email protected]1826a402014-01-08 15:40:48485class BeforeNetworkStartHandler {
486 public:
487 explicit BeforeNetworkStartHandler(bool defer)
488 : defer_on_before_network_start_(defer),
489 observed_before_network_start_(false) {}
490
491 void OnBeforeNetworkStart(bool* defer) {
492 *defer = defer_on_before_network_start_;
493 observed_before_network_start_ = true;
494 }
495
496 bool observed_before_network_start() const {
497 return observed_before_network_start_;
498 }
499
500 private:
501 const bool defer_on_before_network_start_;
502 bool observed_before_network_start_;
503
504 DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
505};
506
ryansturm49a8cb12016-06-15 16:51:09507class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27508 public:
ryansturm49a8cb12016-06-15 16:51:09509 BeforeHeadersSentHandler()
510 : observed_before_headers_sent_with_proxy_(false),
511 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27512
ryansturm49a8cb12016-06-15 16:51:09513 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
514 HttpRequestHeaders* request_headers) {
515 observed_before_headers_sent_ = true;
516 if (!proxy_info.is_http() && !proxy_info.is_https() &&
517 !proxy_info.is_quic()) {
518 return;
519 }
520 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27521 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
522 }
523
ryansturm49a8cb12016-06-15 16:51:09524 bool observed_before_headers_sent_with_proxy() const {
525 return observed_before_headers_sent_with_proxy_;
526 }
527
528 bool observed_before_headers_sent() const {
529 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27530 }
531
532 std::string observed_proxy_server_uri() const {
533 return observed_proxy_server_uri_;
534 }
535
536 private:
ryansturm49a8cb12016-06-15 16:51:09537 bool observed_before_headers_sent_with_proxy_;
538 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27539 std::string observed_proxy_server_uri_;
540
ryansturm49a8cb12016-06-15 16:51:09541 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27542};
543
[email protected]15a5ccf82008-10-23 19:57:43544// Fill |str| with a long header list that consumes >= |size| bytes.
545void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51546 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19547 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
548 const int sizeof_row = strlen(row);
549 const int num_rows = static_cast<int>(
550 ceil(static_cast<float>(size) / sizeof_row));
551 const int sizeof_data = num_rows * sizeof_row;
552 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43553 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51554
[email protected]4ddaf2502008-10-23 18:26:19555 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43556 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19557}
558
thakis84dff942015-07-28 20:47:38559#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29560// Alternative functions that eliminate randomness and dependency on the local
561// host name so that the generated NTLM messages are reproducible.
avibf0746c2015-12-09 19:53:14562void MockGenerateRandom1(uint8_t* output, size_t n) {
563 static const uint8_t bytes[] = {0x55, 0x29, 0x66, 0x26,
564 0x6b, 0x9c, 0x73, 0x54};
[email protected]385a4672009-03-11 22:21:29565 static size_t current_byte = 0;
566 for (size_t i = 0; i < n; ++i) {
567 output[i] = bytes[current_byte++];
568 current_byte %= arraysize(bytes);
569 }
570}
571
avibf0746c2015-12-09 19:53:14572void MockGenerateRandom2(uint8_t* output, size_t n) {
573 static const uint8_t bytes[] = {0x96, 0x79, 0x85, 0xe7, 0x49, 0x93,
574 0x70, 0xa1, 0x4e, 0xe7, 0x87, 0x45,
575 0x31, 0x5b, 0xd3, 0x1f};
[email protected]385a4672009-03-11 22:21:29576 static size_t current_byte = 0;
577 for (size_t i = 0; i < n; ++i) {
578 output[i] = bytes[current_byte++];
579 current_byte %= arraysize(bytes);
580 }
581}
582
[email protected]fe2bc6a2009-03-23 16:52:20583std::string MockGetHostName() {
584 return "WTC-WIN7";
[email protected]385a4672009-03-11 22:21:29585}
thakis84dff942015-07-28 20:47:38586#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29587
[email protected]e60e47a2010-07-14 03:37:18588template<typename ParentPool>
589class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31590 public:
[email protected]9e1bdd32011-02-03 21:48:34591 CaptureGroupNameSocketPool(HostResolver* host_resolver,
592 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18593
[email protected]d80a4322009-08-14 07:07:49594 const std::string last_group_name_received() const {
595 return last_group_name_;
596 }
597
dmichaeld6e570d2014-12-18 22:30:57598 int RequestSocket(const std::string& group_name,
599 const void* socket_params,
600 RequestPriority priority,
mmenked3641e12016-01-28 16:06:15601 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57602 ClientSocketHandle* handle,
603 const CompletionCallback& callback,
604 const BoundNetLog& net_log) override {
[email protected]04e5be32009-06-26 20:00:31605 last_group_name_ = group_name;
606 return ERR_IO_PENDING;
607 }
dmichaeld6e570d2014-12-18 22:30:57608 void CancelRequest(const std::string& group_name,
609 ClientSocketHandle* handle) override {}
610 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09611 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57612 int id) override {}
613 void CloseIdleSockets() override {}
614 int IdleSocketCount() const override { return 0; }
615 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31616 return 0;
617 }
dmichaeld6e570d2014-12-18 22:30:57618 LoadState GetLoadState(const std::string& group_name,
619 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31620 return LOAD_STATE_IDLE;
621 }
dmichaeld6e570d2014-12-18 22:30:57622 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26623 return base::TimeDelta();
624 }
[email protected]d80a4322009-08-14 07:07:49625
626 private:
[email protected]04e5be32009-06-26 20:00:31627 std::string last_group_name_;
628};
629
[email protected]ab739042011-04-07 15:22:28630typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
631CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13632typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
633CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06634typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11635CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18636typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
637CaptureGroupNameSSLSocketPool;
638
rkaplowd90695c2015-03-25 22:12:41639template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18640CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34641 HostResolver* host_resolver,
642 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21643 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18644
hashimoto0d3e4fb2015-01-09 05:02:50645template <>
[email protected]2df19bb2010-08-25 20:13:46646CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21647 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34648 CertVerifier* /* cert_verifier */)
rkaplowd90695c2015-03-25 22:12:41649 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL) {
hashimoto0d3e4fb2015-01-09 05:02:50650}
[email protected]2df19bb2010-08-25 20:13:46651
[email protected]007b3f82013-04-09 08:46:45652template <>
[email protected]e60e47a2010-07-14 03:37:18653CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21654 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34655 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45656 : SSLClientSocketPool(0,
657 0,
[email protected]007b3f82013-04-09 08:46:45658 cert_verifier,
659 NULL,
660 NULL,
[email protected]284303b62013-11-28 15:11:54661 NULL,
eranm6571b2b2014-12-03 15:53:23662 NULL,
[email protected]007b3f82013-04-09 08:46:45663 std::string(),
664 NULL,
665 NULL,
666 NULL,
667 NULL,
668 NULL,
[email protected]8e458552014-08-05 00:02:15669 NULL) {
670}
[email protected]2227c692010-05-04 15:36:11671
[email protected]231d5a32008-09-13 00:45:27672//-----------------------------------------------------------------------------
673
[email protected]79cb5c12011-09-12 13:12:04674// Helper functions for validating that AuthChallengeInfo's are correctly
675// configured for common cases.
676bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
677 if (!auth_challenge)
678 return false;
679 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43680 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04681 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19682 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04683 return true;
684}
685
686bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
687 if (!auth_challenge)
688 return false;
689 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43690 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
691 EXPECT_EQ("MyRealm1", auth_challenge->realm);
692 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
693 return true;
694}
695
696bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
697 if (!auth_challenge)
698 return false;
699 EXPECT_TRUE(auth_challenge->is_proxy);
700 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04701 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19702 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04703 return true;
704}
705
706bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
707 if (!auth_challenge)
708 return false;
709 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43710 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04711 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19712 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04713 return true;
714}
715
thakis84dff942015-07-28 20:47:38716#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04717bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
718 if (!auth_challenge)
719 return false;
720 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43721 EXPECT_EQ("http://172.22.68.17", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04722 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19723 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04724 return true;
725}
thakis84dff942015-07-28 20:47:38726#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04727
[email protected]448d4ca52012-03-04 04:12:23728} // namespace
729
[email protected]23e482282013-06-14 16:08:02730TEST_P(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09731 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
732 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:41733 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]231d5a32008-09-13 00:45:27734}
735
[email protected]23e482282013-06-14 16:08:02736TEST_P(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27737 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35738 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
739 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06740 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27741 };
[email protected]31a2bfe2010-02-09 08:03:39742 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
743 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42744 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27745 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
746 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22747 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
748 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47749 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59750
751 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27752}
753
754// Response with no status line.
[email protected]23e482282013-06-14 16:08:02755TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27756 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35757 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06758 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27759 };
[email protected]31a2bfe2010-02-09 08:03:39760 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
761 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42762 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27763 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
764 EXPECT_EQ("hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22765 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
766 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27767}
768
769// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02770TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27771 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35772 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06773 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27774 };
[email protected]31a2bfe2010-02-09 08:03:39775 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
776 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42777 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27778 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
779 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22780 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
781 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27782}
783
784// Allow up to 4 bytes of junk to precede status line.
[email protected]23e482282013-06-14 16:08:02785TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27786 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35787 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06788 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27789 };
[email protected]31a2bfe2010-02-09 08:03:39790 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
791 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42792 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27793 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
794 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22795 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
796 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27797}
798
799// Beyond 4 bytes of slop and it should fail to find a status line.
[email protected]23e482282013-06-14 16:08:02800TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27801 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35802 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06803 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27804 };
[email protected]31a2bfe2010-02-09 08:03:39805 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
806 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42807 EXPECT_EQ(OK, out.rv);
[email protected]3d2a59b2008-09-26 19:44:25808 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
809 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
sclittlefb249892015-09-10 21:33:22810 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
811 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27812}
813
814// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
[email protected]23e482282013-06-14 16:08:02815TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27816 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35817 MockRead("\n"),
818 MockRead("\n"),
819 MockRead("Q"),
820 MockRead("J"),
821 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06822 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27823 };
[email protected]31a2bfe2010-02-09 08:03:39824 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
825 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42826 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27827 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
828 EXPECT_EQ("DATA", out.response_data);
sclittlefb249892015-09-10 21:33:22829 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
830 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27831}
832
833// Close the connection before enough bytes to have a status line.
[email protected]23e482282013-06-14 16:08:02834TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27835 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35836 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06837 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27838 };
[email protected]31a2bfe2010-02-09 08:03:39839 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
840 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42841 EXPECT_EQ(OK, out.rv);
[email protected]231d5a32008-09-13 00:45:27842 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
843 EXPECT_EQ("HTT", out.response_data);
sclittlefb249892015-09-10 21:33:22844 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
845 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52846}
847
[email protected]f9d44aa2008-09-23 23:57:17848// Simulate a 204 response, lacking a Content-Length header, sent over a
849// persistent connection. The response should still terminate since a 204
850// cannot have a response body.
[email protected]23e482282013-06-14 16:08:02851TEST_P(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19852 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17853 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35854 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19855 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06856 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17857 };
[email protected]31a2bfe2010-02-09 08:03:39858 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
859 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:42860 EXPECT_EQ(OK, out.rv);
[email protected]f9d44aa2008-09-23 23:57:17861 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
862 EXPECT_EQ("", out.response_data);
sclittlefb249892015-09-10 21:33:22863 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
864 int64_t response_size = reads_size - strlen(junk);
865 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17866}
867
[email protected]0877e3d2009-10-17 22:29:57868// A simple request using chunked encoding with some extra data after.
[email protected]23e482282013-06-14 16:08:02869TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19870 std::string final_chunk = "0\r\n\r\n";
871 std::string extra_data = "HTTP/1.1 200 OK\r\n";
872 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57873 MockRead data_reads[] = {
874 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
875 MockRead("5\r\nHello\r\n"),
876 MockRead("1\r\n"),
877 MockRead(" \r\n"),
878 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19879 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06880 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57881 };
[email protected]31a2bfe2010-02-09 08:03:39882 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
883 arraysize(data_reads));
[email protected]0877e3d2009-10-17 22:29:57884 EXPECT_EQ(OK, out.rv);
885 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
886 EXPECT_EQ("Hello world", out.response_data);
sclittlefb249892015-09-10 21:33:22887 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
888 int64_t response_size = reads_size - extra_data.size();
889 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:57890}
891
[email protected]9fe44f52010-09-23 18:36:00892// Next tests deal with http://crbug.com/56344.
893
[email protected]23e482282013-06-14 16:08:02894TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00895 MultipleContentLengthHeadersNoTransferEncoding) {
896 MockRead data_reads[] = {
897 MockRead("HTTP/1.1 200 OK\r\n"),
898 MockRead("Content-Length: 10\r\n"),
899 MockRead("Content-Length: 5\r\n\r\n"),
900 };
901 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
902 arraysize(data_reads));
903 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
904}
905
[email protected]23e482282013-06-14 16:08:02906TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04907 DuplicateContentLengthHeadersNoTransferEncoding) {
908 MockRead data_reads[] = {
909 MockRead("HTTP/1.1 200 OK\r\n"),
910 MockRead("Content-Length: 5\r\n"),
911 MockRead("Content-Length: 5\r\n\r\n"),
912 MockRead("Hello"),
913 };
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", out.response_data);
919}
920
[email protected]23e482282013-06-14 16:08:02921TEST_P(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04922 ComplexContentLengthHeadersNoTransferEncoding) {
923 // More than 2 dupes.
924 {
925 MockRead data_reads[] = {
926 MockRead("HTTP/1.1 200 OK\r\n"),
927 MockRead("Content-Length: 5\r\n"),
928 MockRead("Content-Length: 5\r\n"),
929 MockRead("Content-Length: 5\r\n\r\n"),
930 MockRead("Hello"),
931 };
932 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
933 arraysize(data_reads));
934 EXPECT_EQ(OK, out.rv);
935 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
936 EXPECT_EQ("Hello", out.response_data);
937 }
938 // HTTP/1.0
939 {
940 MockRead data_reads[] = {
941 MockRead("HTTP/1.0 200 OK\r\n"),
942 MockRead("Content-Length: 5\r\n"),
943 MockRead("Content-Length: 5\r\n"),
944 MockRead("Content-Length: 5\r\n\r\n"),
945 MockRead("Hello"),
946 };
947 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
948 arraysize(data_reads));
949 EXPECT_EQ(OK, out.rv);
950 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
951 EXPECT_EQ("Hello", out.response_data);
952 }
953 // 2 dupes and one mismatched.
954 {
955 MockRead data_reads[] = {
956 MockRead("HTTP/1.1 200 OK\r\n"),
957 MockRead("Content-Length: 10\r\n"),
958 MockRead("Content-Length: 10\r\n"),
959 MockRead("Content-Length: 5\r\n\r\n"),
960 };
961 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
962 arraysize(data_reads));
963 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
964 }
965}
966
[email protected]23e482282013-06-14 16:08:02967TEST_P(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00968 MultipleContentLengthHeadersTransferEncoding) {
969 MockRead data_reads[] = {
970 MockRead("HTTP/1.1 200 OK\r\n"),
971 MockRead("Content-Length: 666\r\n"),
972 MockRead("Content-Length: 1337\r\n"),
973 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
974 MockRead("5\r\nHello\r\n"),
975 MockRead("1\r\n"),
976 MockRead(" \r\n"),
977 MockRead("5\r\nworld\r\n"),
978 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:06979 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:00980 };
981 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
982 arraysize(data_reads));
983 EXPECT_EQ(OK, out.rv);
984 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
985 EXPECT_EQ("Hello world", out.response_data);
986}
987
[email protected]1628fe92011-10-04 23:04:55988// Next tests deal with http://crbug.com/98895.
989
990// Checks that a single Content-Disposition header results in no error.
[email protected]23e482282013-06-14 16:08:02991TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:55992 MockRead data_reads[] = {
993 MockRead("HTTP/1.1 200 OK\r\n"),
994 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
995 MockRead("Content-Length: 5\r\n\r\n"),
996 MockRead("Hello"),
997 };
998 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
999 arraysize(data_reads));
1000 EXPECT_EQ(OK, out.rv);
1001 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1002 EXPECT_EQ("Hello", out.response_data);
1003}
1004
[email protected]54a9c6e52012-03-21 20:10:591005// Checks that two identical Content-Disposition headers result in no error.
[email protected]23e482282013-06-14 16:08:021006TEST_P(HttpNetworkTransactionTest,
[email protected]54a9c6e52012-03-21 20:10:591007 TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551008 MockRead data_reads[] = {
1009 MockRead("HTTP/1.1 200 OK\r\n"),
1010 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1011 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1012 MockRead("Content-Length: 5\r\n\r\n"),
1013 MockRead("Hello"),
1014 };
1015 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1016 arraysize(data_reads));
[email protected]54a9c6e52012-03-21 20:10:591017 EXPECT_EQ(OK, out.rv);
1018 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1019 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551020}
1021
1022// Checks that two distinct Content-Disposition headers result in an error.
[email protected]23e482282013-06-14 16:08:021023TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551024 MockRead data_reads[] = {
1025 MockRead("HTTP/1.1 200 OK\r\n"),
1026 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1027 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1028 MockRead("Content-Length: 5\r\n\r\n"),
1029 MockRead("Hello"),
1030 };
1031 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1032 arraysize(data_reads));
1033 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
1034}
1035
[email protected]54a9c6e52012-03-21 20:10:591036// Checks that two identical Location headers result in no error.
1037// Also tests Location header behavior.
[email protected]23e482282013-06-14 16:08:021038TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551039 MockRead data_reads[] = {
1040 MockRead("HTTP/1.1 302 Redirect\r\n"),
1041 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591042 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551043 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061044 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551045 };
1046
1047 HttpRequestInfo request;
1048 request.method = "GET";
1049 request.url = GURL("http://redirect.com/");
1050 request.load_flags = 0;
1051
danakj1fd259a02016-04-16 03:17:091052 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1053 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411054 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]1628fe92011-10-04 23:04:551055
1056 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071057 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551058
[email protected]49639fa2011-12-20 23:22:411059 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551060
[email protected]49639fa2011-12-20 23:22:411061 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1628fe92011-10-04 23:04:551062 EXPECT_EQ(ERR_IO_PENDING, rv);
1063
1064 EXPECT_EQ(OK, callback.WaitForResult());
1065
1066 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521067 ASSERT_TRUE(response);
1068 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551069 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1070 std::string url;
1071 EXPECT_TRUE(response->headers->IsRedirect(&url));
1072 EXPECT_EQ("http://good.com/", url);
[email protected]d8fc4722014-06-13 13:17:151073 EXPECT_TRUE(response->proxy_server.IsEmpty());
[email protected]1628fe92011-10-04 23:04:551074}
1075
[email protected]1628fe92011-10-04 23:04:551076// Checks that two distinct Location headers result in an error.
[email protected]23e482282013-06-14 16:08:021077TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551078 MockRead data_reads[] = {
1079 MockRead("HTTP/1.1 302 Redirect\r\n"),
1080 MockRead("Location: http://good.com/\r\n"),
1081 MockRead("Location: http://evil.com/\r\n"),
1082 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061083 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551084 };
1085 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1086 arraysize(data_reads));
1087 EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
1088}
1089
[email protected]ef0faf2e72009-03-05 23:27:231090// Do a request using the HEAD method. Verify that we don't try to read the
1091// message body (since HEAD has none).
[email protected]23e482282013-06-14 16:08:021092TEST_P(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421093 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231094 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231095 request.url = GURL("http://www.example.org/");
[email protected]ef0faf2e72009-03-05 23:27:231096 request.load_flags = 0;
1097
danakj1fd259a02016-04-16 03:17:091098 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1099 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411100 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
ryansturm49a8cb12016-06-15 16:51:091101 BeforeHeadersSentHandler headers_handler;
1102 trans->SetBeforeHeadersSentCallback(
1103 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1104 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271105
[email protected]ef0faf2e72009-03-05 23:27:231106 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131107 MockWrite("HEAD / HTTP/1.1\r\n"
1108 "Host: www.example.org\r\n"
1109 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231110 };
1111 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231112 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1113 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231114
mmenked39192ee2015-12-09 00:57:231115 // No response body because the test stops reading here.
1116 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231117 };
1118
[email protected]31a2bfe2010-02-09 08:03:391119 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
1120 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:071121 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231122
[email protected]49639fa2011-12-20 23:22:411123 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231124
[email protected]49639fa2011-12-20 23:22:411125 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421126 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ef0faf2e72009-03-05 23:27:231127
1128 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421129 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231130
[email protected]1c773ea12009-04-28 19:58:421131 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521132 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231133
1134 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521135 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231136 EXPECT_EQ(1234, response->headers->GetContentLength());
1137 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151138 EXPECT_TRUE(response->proxy_server.IsEmpty());
ryansturm49a8cb12016-06-15 16:51:091139 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1140 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231141
1142 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101143 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231144 bool has_server_header = response->headers->EnumerateHeader(
1145 &iter, "Server", &server_header);
1146 EXPECT_TRUE(has_server_header);
1147 EXPECT_EQ("Blah", server_header);
1148
1149 // Reading should give EOF right away, since there is no message body
1150 // (despite non-zero content-length).
1151 std::string response_data;
1152 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421153 EXPECT_EQ(OK, rv);
[email protected]ef0faf2e72009-03-05 23:27:231154 EXPECT_EQ("", response_data);
1155}
1156
[email protected]23e482282013-06-14 16:08:021157TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091158 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521159
1160 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351161 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1162 MockRead("hello"),
1163 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1164 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061165 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521166 };
[email protected]31a2bfe2010-02-09 08:03:391167 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071168 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521169
[email protected]0b0bf032010-09-21 18:08:501170 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521171 "hello", "world"
1172 };
1173
1174 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421175 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521176 request.method = "GET";
bncce36dca22015-04-21 22:11:231177 request.url = GURL("http://www.example.org/");
initial.commit586acc5fe2008-07-26 22:42:521178 request.load_flags = 0;
1179
danakj1fd259a02016-04-16 03:17:091180 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501181 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271182
[email protected]49639fa2011-12-20 23:22:411183 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521184
[email protected]49639fa2011-12-20 23:22:411185 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421186 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521187
1188 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421189 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521190
[email protected]1c773ea12009-04-28 19:58:421191 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521192 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521193
wezca1070932016-05-26 20:30:521194 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251195 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]d8fc4722014-06-13 13:17:151196 EXPECT_TRUE(response->proxy_server.IsEmpty());
initial.commit586acc5fe2008-07-26 22:42:521197
1198 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571199 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421200 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251201 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521202 }
1203}
1204
[email protected]23e482282013-06-14 16:08:021205TEST_P(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091206 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221207 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:091208 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:221209 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271210
[email protected]1c773ea12009-04-28 19:58:421211 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521212 request.method = "POST";
1213 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271214 request.upload_data_stream = &upload_data_stream;
initial.commit586acc5fe2008-07-26 22:42:521215 request.load_flags = 0;
1216
danakj1fd259a02016-04-16 03:17:091217 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1218 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411219 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271220
initial.commit586acc5fe2008-07-26 22:42:521221 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351222 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1223 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1224 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061225 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521226 };
[email protected]31a2bfe2010-02-09 08:03:391227 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071228 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521229
[email protected]49639fa2011-12-20 23:22:411230 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521231
[email protected]49639fa2011-12-20 23:22:411232 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421233 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521234
1235 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421236 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521237
[email protected]1c773ea12009-04-28 19:58:421238 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521239 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521240
wezca1070932016-05-26 20:30:521241 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251242 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521243
1244 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571245 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421246 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251247 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521248}
1249
[email protected]3a2d3662009-03-27 03:49:141250// This test is almost the same as Ignores100 above, but the response contains
1251// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571252// HTTP/1.1 and the two status headers are read in one read.
[email protected]23e482282013-06-14 16:08:021253TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421254 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141255 request.method = "GET";
1256 request.url = GURL("http://www.foo.com/");
1257 request.load_flags = 0;
1258
danakj1fd259a02016-04-16 03:17:091259 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1260 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411261 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271262
[email protected]3a2d3662009-03-27 03:49:141263 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571264 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1265 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141266 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061267 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141268 };
[email protected]31a2bfe2010-02-09 08:03:391269 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071270 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141271
[email protected]49639fa2011-12-20 23:22:411272 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141273
[email protected]49639fa2011-12-20 23:22:411274 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421275 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3a2d3662009-03-27 03:49:141276
1277 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421278 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141279
[email protected]1c773ea12009-04-28 19:58:421280 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521281 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141282
wezca1070932016-05-26 20:30:521283 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141284 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1285
1286 std::string response_data;
1287 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421288 EXPECT_EQ(OK, rv);
[email protected]3a2d3662009-03-27 03:49:141289 EXPECT_EQ("hello world", response_data);
1290}
1291
[email protected]23e482282013-06-14 16:08:021292TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081293 HttpRequestInfo request;
1294 request.method = "POST";
1295 request.url = GURL("http://www.foo.com/");
1296 request.load_flags = 0;
1297
danakj1fd259a02016-04-16 03:17:091298 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1299 std::unique_ptr<HttpTransaction> trans(
zmo9528c9f42015-08-04 22:12:081300 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1301
1302 MockRead data_reads[] = {
1303 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1304 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381305 };
zmo9528c9f42015-08-04 22:12:081306 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1307 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381308
zmo9528c9f42015-08-04 22:12:081309 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381310
zmo9528c9f42015-08-04 22:12:081311 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1312 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]ee9410e72010-01-07 01:42:381313
zmo9528c9f42015-08-04 22:12:081314 rv = callback.WaitForResult();
1315 EXPECT_EQ(OK, rv);
[email protected]ee9410e72010-01-07 01:42:381316
zmo9528c9f42015-08-04 22:12:081317 std::string response_data;
1318 rv = ReadTransaction(trans.get(), &response_data);
1319 EXPECT_EQ(OK, rv);
1320 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381321}
1322
[email protected]23e482282013-06-14 16:08:021323TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381324 HttpRequestInfo request;
1325 request.method = "POST";
1326 request.url = GURL("http://www.foo.com/");
1327 request.load_flags = 0;
1328
danakj1fd259a02016-04-16 03:17:091329 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1330 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411331 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271332
[email protected]ee9410e72010-01-07 01:42:381333 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061334 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381335 };
[email protected]31a2bfe2010-02-09 08:03:391336 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071337 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381338
[email protected]49639fa2011-12-20 23:22:411339 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381340
[email protected]49639fa2011-12-20 23:22:411341 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]ee9410e72010-01-07 01:42:381342 EXPECT_EQ(ERR_IO_PENDING, rv);
1343
1344 rv = callback.WaitForResult();
1345 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
1346}
1347
[email protected]23e482282013-06-14 16:08:021348void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511349 const MockWrite* write_failure,
1350 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421351 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521352 request.method = "GET";
1353 request.url = GURL("http://www.foo.com/");
1354 request.load_flags = 0;
1355
vishal.b62985ca92015-04-17 08:45:511356 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071357 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091358 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271359
[email protected]202965992011-12-07 23:04:511360 // Written data for successfully sending both requests.
1361 MockWrite data1_writes[] = {
1362 MockWrite("GET / HTTP/1.1\r\n"
1363 "Host: www.foo.com\r\n"
1364 "Connection: keep-alive\r\n\r\n"),
1365 MockWrite("GET / HTTP/1.1\r\n"
1366 "Host: www.foo.com\r\n"
1367 "Connection: keep-alive\r\n\r\n")
1368 };
1369
1370 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521371 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351372 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1373 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061374 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521375 };
[email protected]202965992011-12-07 23:04:511376
1377 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491378 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511379 data1_writes[1] = *write_failure;
1380 } else {
1381 ASSERT_TRUE(read_failure);
1382 data1_reads[2] = *read_failure;
1383 }
1384
1385 StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
1386 data1_writes, arraysize(data1_writes));
[email protected]bb88e1d32013-05-03 23:11:071387 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521388
1389 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351390 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1391 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061392 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521393 };
[email protected]31a2bfe2010-02-09 08:03:391394 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071395 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521396
thestig9d3bb0c2015-01-24 00:49:511397 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521398 "hello", "world"
1399 };
1400
avibf0746c2015-12-09 19:53:141401 uint32_t first_socket_log_id = NetLog::Source::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521402 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411403 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521404
danakj1fd259a02016-04-16 03:17:091405 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501406 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
initial.commit586acc5fe2008-07-26 22:42:521407
[email protected]49639fa2011-12-20 23:22:411408 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421409 EXPECT_EQ(ERR_IO_PENDING, rv);
initial.commit586acc5fe2008-07-26 22:42:521410
1411 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421412 EXPECT_EQ(OK, rv);
initial.commit586acc5fe2008-07-26 22:42:521413
[email protected]58e32bb2013-01-21 18:23:251414 LoadTimingInfo load_timing_info;
1415 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1416 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1417 if (i == 0) {
1418 first_socket_log_id = load_timing_info.socket_log_id;
1419 } else {
1420 // The second request should be using a new socket.
1421 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1422 }
1423
[email protected]1c773ea12009-04-28 19:58:421424 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521425 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521426
wezca1070932016-05-26 20:30:521427 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251428 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521429
1430 std::string response_data;
[email protected]af4876d2008-10-21 23:10:571431 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:421432 EXPECT_EQ(OK, rv);
[email protected]3d2a59b2008-09-26 19:44:251433 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521434 }
1435}
[email protected]3d2a59b2008-09-26 19:44:251436
[email protected]a34f61ee2014-03-18 20:59:491437void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1438 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101439 const MockRead* read_failure,
1440 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491441 HttpRequestInfo request;
1442 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101443 request.url = GURL("https://www.foo.com/");
[email protected]a34f61ee2014-03-18 20:59:491444 request.load_flags = 0;
1445
vishal.b62985ca92015-04-17 08:45:511446 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491447 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091448 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491449
[email protected]09356c652014-03-25 15:36:101450 SSLSocketDataProvider ssl1(ASYNC, OK);
1451 SSLSocketDataProvider ssl2(ASYNC, OK);
1452 if (use_spdy) {
rdsmithebb50aa2015-11-12 03:44:381453 ssl1.SetNextProto(GetProtocol());
1454 ssl2.SetNextProto(GetProtocol());
[email protected]09356c652014-03-25 15:36:101455 }
1456 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1457 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491458
[email protected]09356c652014-03-25 15:36:101459 // SPDY versions of the request and response.
danakj1fd259a02016-04-16 03:17:091460 std::unique_ptr<SpdySerializedFrame> spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491461 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
danakj1fd259a02016-04-16 03:17:091462 std::unique_ptr<SpdySerializedFrame> spdy_response(
[email protected]09356c652014-03-25 15:36:101463 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:091464 std::unique_ptr<SpdySerializedFrame> spdy_data(
[email protected]09356c652014-03-25 15:36:101465 spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
[email protected]a34f61ee2014-03-18 20:59:491466
[email protected]09356c652014-03-25 15:36:101467 // HTTP/1.1 versions of the request and response.
1468 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1469 "Host: www.foo.com\r\n"
1470 "Connection: keep-alive\r\n\r\n";
1471 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1472 const char kHttpData[] = "hello";
1473
1474 std::vector<MockRead> data1_reads;
1475 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491476 if (write_failure) {
1477 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101478 data1_writes.push_back(*write_failure);
1479 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491480 } else {
1481 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101482 if (use_spdy) {
1483 data1_writes.push_back(CreateMockWrite(*spdy_request));
1484 } else {
1485 data1_writes.push_back(MockWrite(kHttpRequest));
1486 }
1487 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491488 }
1489
[email protected]09356c652014-03-25 15:36:101490 StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
1491 &data1_writes[0], data1_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491492 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1493
[email protected]09356c652014-03-25 15:36:101494 std::vector<MockRead> data2_reads;
1495 std::vector<MockWrite> data2_writes;
1496
1497 if (use_spdy) {
1498 data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
1499
1500 data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
1501 data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
1502 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1503 } else {
1504 data2_writes.push_back(
1505 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1506
1507 data2_reads.push_back(
1508 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1509 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1510 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1511 }
rch8e6c6c42015-05-01 14:05:131512 SequencedSocketData data2(&data2_reads[0], data2_reads.size(),
1513 &data2_writes[0], data2_writes.size());
[email protected]a34f61ee2014-03-18 20:59:491514 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1515
1516 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591517 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491518 // Wait for the preconnect to complete.
1519 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1520 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101521 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491522
1523 // Make the request.
1524 TestCompletionCallback callback;
1525
danakj1fd259a02016-04-16 03:17:091526 std::unique_ptr<HttpTransaction> trans(
[email protected]a34f61ee2014-03-18 20:59:491527 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1528
1529 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1530 EXPECT_EQ(ERR_IO_PENDING, rv);
1531
1532 rv = callback.WaitForResult();
1533 EXPECT_EQ(OK, rv);
1534
1535 LoadTimingInfo load_timing_info;
1536 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101537 TestLoadTimingNotReused(
1538 load_timing_info,
1539 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491540
1541 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:521542 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491543
wezca1070932016-05-26 20:30:521544 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021545 if (response->was_fetched_via_spdy) {
1546 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1547 } else {
1548 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1549 }
[email protected]a34f61ee2014-03-18 20:59:491550
1551 std::string response_data;
1552 rv = ReadTransaction(trans.get(), &response_data);
1553 EXPECT_EQ(OK, rv);
[email protected]09356c652014-03-25 15:36:101554 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491555}
1556
[email protected]23e482282013-06-14 16:08:021557TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:231558 KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061559 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511560 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1561}
1562
[email protected]23e482282013-06-14 16:08:021563TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061564 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511565 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251566}
1567
[email protected]23e482282013-06-14 16:08:021568TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061569 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511570 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251571}
1572
[email protected]d58ceea82014-06-04 10:55:541573// Make sure that on a 408 response (Request Timeout), the request is retried,
1574// if the socket was a reused keep alive socket.
1575TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
1576 MockRead read_failure(SYNCHRONOUS,
1577 "HTTP/1.1 408 Request Timeout\r\n"
1578 "Connection: Keep-Alive\r\n"
1579 "Content-Length: 6\r\n\r\n"
1580 "Pickle");
1581 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1582}
1583
[email protected]a34f61ee2014-03-18 20:59:491584TEST_P(HttpNetworkTransactionTest,
1585 PreconnectErrorNotConnectedOnWrite) {
1586 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101587 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491588}
1589
1590TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
1591 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101592 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491593}
1594
1595TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
1596 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101597 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1598}
1599
1600TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
1601 MockRead read_failure(ASYNC, OK); // EOF
1602 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1603}
1604
[email protected]d58ceea82014-06-04 10:55:541605// Make sure that on a 408 response (Request Timeout), the request is retried,
1606// if the socket was a preconnected (UNUSED_IDLE) socket.
1607TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
1608 MockRead read_failure(SYNCHRONOUS,
1609 "HTTP/1.1 408 Request Timeout\r\n"
1610 "Connection: Keep-Alive\r\n"
1611 "Content-Length: 6\r\n\r\n"
1612 "Pickle");
1613 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1614 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1615}
1616
[email protected]09356c652014-03-25 15:36:101617TEST_P(HttpNetworkTransactionTest,
1618 SpdyPreconnectErrorNotConnectedOnWrite) {
1619 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1620 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1621}
1622
1623TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
1624 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1625 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1626}
1627
1628TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
1629 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1630 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1631}
1632
1633TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
1634 MockRead read_failure(ASYNC, OK); // EOF
1635 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491636}
1637
[email protected]23e482282013-06-14 16:08:021638TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421639 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251640 request.method = "GET";
bncce36dca22015-04-21 22:11:231641 request.url = GURL("http://www.example.org/");
[email protected]3d2a59b2008-09-26 19:44:251642 request.load_flags = 0;
1643
danakj1fd259a02016-04-16 03:17:091644 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1645 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:411646 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:271647
[email protected]3d2a59b2008-09-26 19:44:251648 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061649 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351650 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1651 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061652 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251653 };
[email protected]31a2bfe2010-02-09 08:03:391654 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071655 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251656
[email protected]49639fa2011-12-20 23:22:411657 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251658
[email protected]49639fa2011-12-20 23:22:411659 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:421660 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3d2a59b2008-09-26 19:44:251661
1662 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:421663 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
ttuttled9dbc652015-09-29 20:00:591664
1665 IPEndPoint endpoint;
1666 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
1667 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251668}
1669
1670// What do various browsers do when the server closes a non-keepalive
1671// connection without sending any response header or body?
1672//
1673// IE7: error page
1674// Safari 3.1.2 (Windows): error page
1675// Firefox 3.0.1: blank page
1676// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421677// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1678// Us: error page (EMPTY_RESPONSE)
[email protected]23e482282013-06-14 16:08:021679TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251680 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061681 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351682 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1683 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061684 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251685 };
[email protected]31a2bfe2010-02-09 08:03:391686 SimpleGetHelperResult out = SimpleGetHelper(data_reads,
1687 arraysize(data_reads));
[email protected]1c773ea12009-04-28 19:58:421688 EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
[email protected]3d2a59b2008-09-26 19:44:251689}
[email protected]038e9a32008-10-08 22:40:161690
[email protected]1826a402014-01-08 15:40:481691// Test that network access can be deferred and resumed.
1692TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
1693 HttpRequestInfo request;
1694 request.method = "GET";
bncce36dca22015-04-21 22:11:231695 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481696 request.load_flags = 0;
1697
danakj1fd259a02016-04-16 03:17:091698 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1699 std::unique_ptr<HttpTransaction> trans(
[email protected]1826a402014-01-08 15:40:481700 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1701
1702 // Defer on OnBeforeNetworkStart.
1703 BeforeNetworkStartHandler net_start_handler(true); // defer
1704 trans->SetBeforeNetworkStartCallback(
1705 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1706 base::Unretained(&net_start_handler)));
1707
1708 MockRead data_reads[] = {
1709 MockRead("HTTP/1.0 200 OK\r\n"),
1710 MockRead("Content-Length: 5\r\n\r\n"),
1711 MockRead("hello"),
1712 MockRead(SYNCHRONOUS, 0),
1713 };
1714 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
1715 session_deps_.socket_factory->AddSocketDataProvider(&data);
1716
1717 TestCompletionCallback callback;
1718
1719 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1720 EXPECT_EQ(ERR_IO_PENDING, rv);
fdoray92e35a72016-06-10 15:54:551721 base::RunLoop().RunUntilIdle();
[email protected]1826a402014-01-08 15:40:481722
1723 // Should have deferred for network start.
1724 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1725 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481726
1727 trans->ResumeNetworkStart();
1728 rv = callback.WaitForResult();
1729 EXPECT_EQ(OK, rv);
wezca1070932016-05-26 20:30:521730 EXPECT_TRUE(trans->GetResponseInfo());
[email protected]1826a402014-01-08 15:40:481731
1732 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
1733 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
1734 if (rv == ERR_IO_PENDING)
1735 rv = callback.WaitForResult();
1736 EXPECT_EQ(5, rv);
1737 trans.reset();
1738}
1739
1740// Test that network use can be deferred and canceled.
1741TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
1742 HttpRequestInfo request;
1743 request.method = "GET";
bncce36dca22015-04-21 22:11:231744 request.url = GURL("http://www.example.org/");
[email protected]1826a402014-01-08 15:40:481745 request.load_flags = 0;
1746
danakj1fd259a02016-04-16 03:17:091747 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1748 std::unique_ptr<HttpTransaction> trans(
[email protected]1826a402014-01-08 15:40:481749 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
1750
1751 // Defer on OnBeforeNetworkStart.
1752 BeforeNetworkStartHandler net_start_handler(true); // defer
1753 trans->SetBeforeNetworkStartCallback(
1754 base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
1755 base::Unretained(&net_start_handler)));
1756
1757 TestCompletionCallback callback;
1758
1759 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1760 EXPECT_EQ(ERR_IO_PENDING, rv);
fdoray92e35a72016-06-10 15:54:551761 base::RunLoop().RunUntilIdle();
[email protected]1826a402014-01-08 15:40:481762
1763 // Should have deferred for network start.
1764 EXPECT_TRUE(net_start_handler.observed_before_network_start());
1765 EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
[email protected]1826a402014-01-08 15:40:481766}
1767
[email protected]7a5378b2012-11-04 03:25:171768// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1769// tests. There was a bug causing HttpNetworkTransaction to hang in the
1770// destructor in such situations.
1771// See http://crbug.com/154712 and http://crbug.com/156609.
[email protected]23e482282013-06-14 16:08:021772TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171773 HttpRequestInfo request;
1774 request.method = "GET";
bncce36dca22015-04-21 22:11:231775 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171776 request.load_flags = 0;
1777
danakj1fd259a02016-04-16 03:17:091778 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1779 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501780 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171781
1782 MockRead data_reads[] = {
1783 MockRead("HTTP/1.0 200 OK\r\n"),
1784 MockRead("Connection: keep-alive\r\n"),
1785 MockRead("Content-Length: 100\r\n\r\n"),
1786 MockRead("hello"),
1787 MockRead(SYNCHRONOUS, 0),
1788 };
1789 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071790 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171791
1792 TestCompletionCallback callback;
1793
1794 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1795 EXPECT_EQ(ERR_IO_PENDING, rv);
1796
1797 rv = callback.WaitForResult();
1798 EXPECT_EQ(OK, rv);
1799
1800 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501801 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171802 if (rv == ERR_IO_PENDING)
1803 rv = callback.WaitForResult();
1804 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501805 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171806 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1807
1808 trans.reset();
fdoray92e35a72016-06-10 15:54:551809 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171810 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1811}
1812
[email protected]23e482282013-06-14 16:08:021813TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171814 HttpRequestInfo request;
1815 request.method = "GET";
bncce36dca22015-04-21 22:11:231816 request.url = GURL("http://www.example.org/");
[email protected]7a5378b2012-11-04 03:25:171817 request.load_flags = 0;
1818
danakj1fd259a02016-04-16 03:17:091819 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1820 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501821 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a5378b2012-11-04 03:25:171822
1823 MockRead data_reads[] = {
1824 MockRead("HTTP/1.0 200 OK\r\n"),
1825 MockRead("Connection: keep-alive\r\n"),
1826 MockRead("Content-Length: 100\r\n\r\n"),
1827 MockRead(SYNCHRONOUS, 0),
1828 };
1829 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:071830 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171831
1832 TestCompletionCallback callback;
1833
1834 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
1835 EXPECT_EQ(ERR_IO_PENDING, rv);
1836
1837 rv = callback.WaitForResult();
1838 EXPECT_EQ(OK, rv);
1839
1840 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
[email protected]90499482013-06-01 00:39:501841 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171842 if (rv == ERR_IO_PENDING)
1843 rv = callback.WaitForResult();
1844 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
1845
1846 trans.reset();
fdoray92e35a72016-06-10 15:54:551847 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171848 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1849}
1850
[email protected]0b0bf032010-09-21 18:08:501851// Test that we correctly reuse a keep-alive connection after not explicitly
1852// reading the body.
[email protected]23e482282013-06-14 16:08:021853TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131854 HttpRequestInfo request;
1855 request.method = "GET";
1856 request.url = GURL("http://www.foo.com/");
1857 request.load_flags = 0;
1858
vishal.b62985ca92015-04-17 08:45:511859 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071860 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091861 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271862
mmenkecc2298e2015-12-07 18:20:181863 const char* request_data =
1864 "GET / HTTP/1.1\r\n"
1865 "Host: www.foo.com\r\n"
1866 "Connection: keep-alive\r\n\r\n";
1867 MockWrite data_writes[] = {
1868 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1869 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1870 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1871 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1872 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1873 };
1874
[email protected]0b0bf032010-09-21 18:08:501875 // Note that because all these reads happen in the same
1876 // StaticSocketDataProvider, it shows that the same socket is being reused for
1877 // all transactions.
mmenkecc2298e2015-12-07 18:20:181878 MockRead data_reads[] = {
1879 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
1880 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
1881 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
1882 MockRead(ASYNC, 7,
1883 "HTTP/1.1 302 Found\r\n"
1884 "Content-Length: 0\r\n\r\n"),
1885 MockRead(ASYNC, 9,
1886 "HTTP/1.1 302 Found\r\n"
1887 "Content-Length: 5\r\n\r\n"
1888 "hello"),
1889 MockRead(ASYNC, 11,
1890 "HTTP/1.1 301 Moved Permanently\r\n"
1891 "Content-Length: 0\r\n\r\n"),
1892 MockRead(ASYNC, 13,
1893 "HTTP/1.1 301 Moved Permanently\r\n"
1894 "Content-Length: 5\r\n\r\n"
1895 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131896
mmenkecc2298e2015-12-07 18:20:181897 // In the next two rounds, IsConnectedAndIdle returns false, due to
1898 // the set_busy_before_sync_reads(true) call, while the
1899 // HttpNetworkTransaction is being shut down, but the socket is still
1900 // reuseable. See http://crbug.com/544255.
1901 MockRead(ASYNC, 15,
1902 "HTTP/1.1 200 Hunky-Dory\r\n"
1903 "Content-Length: 5\r\n\r\n"),
1904 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:131905
mmenkecc2298e2015-12-07 18:20:181906 MockRead(ASYNC, 18,
1907 "HTTP/1.1 200 Hunky-Dory\r\n"
1908 "Content-Length: 5\r\n\r\n"
1909 "he"),
1910 MockRead(SYNCHRONOUS, 19, "llo"),
1911
1912 // The body of the final request is actually read.
1913 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1914 MockRead(ASYNC, 22, "hello"),
1915 };
1916 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
1917 arraysize(data_writes));
1918 data.set_busy_before_sync_reads(true);
1919 session_deps_.socket_factory->AddSocketDataProvider(&data);
1920
1921 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:501922 std::string response_lines[kNumUnreadBodies];
1923
avibf0746c2015-12-09 19:53:141924 uint32_t first_socket_log_id = NetLog::Source::kInvalidId;
mmenkecc2298e2015-12-07 18:20:181925 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:411926 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:131927
danakj1fd259a02016-04-16 03:17:091928 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501929 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]fc31d6a42010-06-24 18:05:131930
[email protected]49639fa2011-12-20 23:22:411931 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
mmenkecc2298e2015-12-07 18:20:181932 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]fc31d6a42010-06-24 18:05:131933
[email protected]58e32bb2013-01-21 18:23:251934 LoadTimingInfo load_timing_info;
1935 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
1936 if (i == 0) {
1937 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1938 first_socket_log_id = load_timing_info.socket_log_id;
1939 } else {
1940 TestLoadTimingReused(load_timing_info);
1941 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
1942 }
1943
[email protected]fc31d6a42010-06-24 18:05:131944 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:181945 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:131946
mmenkecc2298e2015-12-07 18:20:181947 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:501948 response_lines[i] = response->headers->GetStatusLine();
1949
mmenkecc2298e2015-12-07 18:20:181950 // Delete the transaction without reading the response bodies. Then spin
1951 // the message loop, so the response bodies are drained.
1952 trans.reset();
1953 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:131954 }
[email protected]0b0bf032010-09-21 18:08:501955
1956 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:181957 "HTTP/1.1 204 No Content",
1958 "HTTP/1.1 205 Reset Content",
1959 "HTTP/1.1 304 Not Modified",
1960 "HTTP/1.1 302 Found",
1961 "HTTP/1.1 302 Found",
1962 "HTTP/1.1 301 Moved Permanently",
1963 "HTTP/1.1 301 Moved Permanently",
1964 "HTTP/1.1 200 Hunky-Dory",
1965 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:501966 };
1967
mostynb91e0da982015-01-20 19:17:271968 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
1969 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:501970
1971 for (int i = 0; i < kNumUnreadBodies; ++i)
1972 EXPECT_EQ(kStatusLines[i], response_lines[i]);
1973
[email protected]49639fa2011-12-20 23:22:411974 TestCompletionCallback callback;
danakj1fd259a02016-04-16 03:17:091975 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:501976 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:411977 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
mmenkecc2298e2015-12-07 18:20:181978 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]0b0bf032010-09-21 18:08:501979 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:181980 ASSERT_TRUE(response);
1981 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:501982 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1983 std::string response_data;
1984 rv = ReadTransaction(trans.get(), &response_data);
1985 EXPECT_EQ(OK, rv);
1986 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:131987}
1988
mmenke5f94fda2016-06-02 20:54:131989// Sockets that receive extra data after a response is complete should not be
1990// reused.
1991TEST_P(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
1992 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1993 MockWrite data_writes1[] = {
1994 MockWrite("HEAD / HTTP/1.1\r\n"
1995 "Host: www.borked.com\r\n"
1996 "Connection: keep-alive\r\n\r\n"),
1997 };
1998
1999 MockRead data_reads1[] = {
2000 MockRead("HTTP/1.1 200 OK\r\n"
2001 "Connection: keep-alive\r\n"
2002 "Content-Length: 22\r\n\r\n"
2003 "This server is borked."),
2004 };
2005
2006 MockWrite data_writes2[] = {
2007 MockWrite("GET /foo HTTP/1.1\r\n"
2008 "Host: www.borked.com\r\n"
2009 "Connection: keep-alive\r\n\r\n"),
2010 };
2011
2012 MockRead data_reads2[] = {
2013 MockRead("HTTP/1.1 200 OK\r\n"
2014 "Content-Length: 3\r\n\r\n"
2015 "foo"),
2016 };
2017 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2018 data_writes1, arraysize(data_writes1));
2019 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2020 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2021 data_writes2, arraysize(data_writes2));
2022 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2023
2024 TestCompletionCallback callback;
2025 HttpRequestInfo request1;
2026 request1.method = "HEAD";
2027 request1.url = GURL("http://www.borked.com/");
2028
2029 std::unique_ptr<HttpTransaction> trans1(
2030 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2031 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
2032 EXPECT_EQ(OK, callback.GetResult(rv));
2033
2034 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2035 ASSERT_TRUE(response1);
2036 ASSERT_TRUE(response1->headers);
2037 EXPECT_EQ(200, response1->headers->response_code());
2038 EXPECT_TRUE(response1->headers->IsKeepAlive());
2039
2040 std::string response_data1;
2041 EXPECT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
2042 EXPECT_EQ("", response_data1);
2043 // Deleting the transaction attempts to release the socket back into the
2044 // socket pool.
2045 trans1.reset();
2046
2047 HttpRequestInfo request2;
2048 request2.method = "GET";
2049 request2.url = GURL("http://www.borked.com/foo");
2050
2051 std::unique_ptr<HttpTransaction> trans2(
2052 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2053 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
2054 EXPECT_EQ(OK, callback.GetResult(rv));
2055
2056 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2057 ASSERT_TRUE(response2);
2058 ASSERT_TRUE(response2->headers);
2059 EXPECT_EQ(200, response2->headers->response_code());
2060
2061 std::string response_data2;
2062 EXPECT_EQ(OK, ReadTransaction(trans2.get(), &response_data2));
2063 EXPECT_EQ("foo", response_data2);
2064}
2065
2066TEST_P(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
2067 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2068 MockWrite data_writes1[] = {
2069 MockWrite("GET / HTTP/1.1\r\n"
2070 "Host: www.borked.com\r\n"
2071 "Connection: keep-alive\r\n\r\n"),
2072 };
2073
2074 MockRead data_reads1[] = {
2075 MockRead("HTTP/1.1 200 OK\r\n"
2076 "Connection: keep-alive\r\n"
2077 "Content-Length: 22\r\n\r\n"
2078 "This server is borked."
2079 "Bonus data!"),
2080 };
2081
2082 MockWrite data_writes2[] = {
2083 MockWrite("GET /foo HTTP/1.1\r\n"
2084 "Host: www.borked.com\r\n"
2085 "Connection: keep-alive\r\n\r\n"),
2086 };
2087
2088 MockRead data_reads2[] = {
2089 MockRead("HTTP/1.1 200 OK\r\n"
2090 "Content-Length: 3\r\n\r\n"
2091 "foo"),
2092 };
2093 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2094 data_writes1, arraysize(data_writes1));
2095 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2096 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2097 data_writes2, arraysize(data_writes2));
2098 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2099
2100 TestCompletionCallback callback;
2101 HttpRequestInfo request1;
2102 request1.method = "GET";
2103 request1.url = GURL("http://www.borked.com/");
2104
2105 std::unique_ptr<HttpTransaction> trans1(
2106 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2107 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
2108 EXPECT_EQ(OK, callback.GetResult(rv));
2109
2110 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2111 ASSERT_TRUE(response1);
2112 ASSERT_TRUE(response1->headers);
2113 EXPECT_EQ(200, response1->headers->response_code());
2114 EXPECT_TRUE(response1->headers->IsKeepAlive());
2115
2116 std::string response_data1;
2117 EXPECT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
2118 EXPECT_EQ("This server is borked.", response_data1);
2119 // Deleting the transaction attempts to release the socket back into the
2120 // socket pool.
2121 trans1.reset();
2122
2123 HttpRequestInfo request2;
2124 request2.method = "GET";
2125 request2.url = GURL("http://www.borked.com/foo");
2126
2127 std::unique_ptr<HttpTransaction> trans2(
2128 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2129 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
2130 EXPECT_EQ(OK, callback.GetResult(rv));
2131
2132 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2133 ASSERT_TRUE(response2);
2134 ASSERT_TRUE(response2->headers);
2135 EXPECT_EQ(200, response2->headers->response_code());
2136
2137 std::string response_data2;
2138 EXPECT_EQ(OK, ReadTransaction(trans2.get(), &response_data2));
2139 EXPECT_EQ("foo", response_data2);
2140}
2141
2142TEST_P(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
2143 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2144 MockWrite data_writes1[] = {
2145 MockWrite("GET / HTTP/1.1\r\n"
2146 "Host: www.borked.com\r\n"
2147 "Connection: keep-alive\r\n\r\n"),
2148 };
2149
2150 MockRead data_reads1[] = {
2151 MockRead("HTTP/1.1 200 OK\r\n"
2152 "Connection: keep-alive\r\n"
2153 "Transfer-Encoding: chunked\r\n\r\n"),
2154 MockRead("16\r\nThis server is borked.\r\n"),
2155 MockRead("0\r\n\r\nBonus data!"),
2156 };
2157
2158 MockWrite data_writes2[] = {
2159 MockWrite("GET /foo HTTP/1.1\r\n"
2160 "Host: www.borked.com\r\n"
2161 "Connection: keep-alive\r\n\r\n"),
2162 };
2163
2164 MockRead data_reads2[] = {
2165 MockRead("HTTP/1.1 200 OK\r\n"
2166 "Content-Length: 3\r\n\r\n"
2167 "foo"),
2168 };
2169 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2170 data_writes1, arraysize(data_writes1));
2171 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2172 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2173 data_writes2, arraysize(data_writes2));
2174 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2175
2176 TestCompletionCallback callback;
2177 HttpRequestInfo request1;
2178 request1.method = "GET";
2179 request1.url = GURL("http://www.borked.com/");
2180
2181 std::unique_ptr<HttpTransaction> trans1(
2182 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2183 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
2184 EXPECT_EQ(OK, callback.GetResult(rv));
2185
2186 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2187 ASSERT_TRUE(response1);
2188 ASSERT_TRUE(response1->headers);
2189 EXPECT_EQ(200, response1->headers->response_code());
2190 EXPECT_TRUE(response1->headers->IsKeepAlive());
2191
2192 std::string response_data1;
2193 EXPECT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
2194 EXPECT_EQ("This server is borked.", response_data1);
2195 // Deleting the transaction attempts to release the socket back into the
2196 // socket pool.
2197 trans1.reset();
2198
2199 HttpRequestInfo request2;
2200 request2.method = "GET";
2201 request2.url = GURL("http://www.borked.com/foo");
2202
2203 std::unique_ptr<HttpTransaction> trans2(
2204 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2205 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
2206 EXPECT_EQ(OK, callback.GetResult(rv));
2207
2208 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2209 ASSERT_TRUE(response2);
2210 ASSERT_TRUE(response2->headers);
2211 EXPECT_EQ(200, response2->headers->response_code());
2212
2213 std::string response_data2;
2214 EXPECT_EQ(OK, ReadTransaction(trans2.get(), &response_data2));
2215 EXPECT_EQ("foo", response_data2);
2216}
2217
2218// This is a little different from the others - it tests the case that the
2219// HttpStreamParser doesn't know if there's extra data on a socket or not when
2220// the HttpNetworkTransaction is torn down, because the response body hasn't
2221// been read from yet, but the request goes through the HttpResponseBodyDrainer.
2222TEST_P(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
2223 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2224 MockWrite data_writes1[] = {
2225 MockWrite("GET / HTTP/1.1\r\n"
2226 "Host: www.borked.com\r\n"
2227 "Connection: keep-alive\r\n\r\n"),
2228 };
2229
2230 MockRead data_reads1[] = {
2231 MockRead("HTTP/1.1 200 OK\r\n"
2232 "Connection: keep-alive\r\n"
2233 "Transfer-Encoding: chunked\r\n\r\n"),
2234 MockRead("16\r\nThis server is borked.\r\n"),
2235 MockRead("0\r\n\r\nBonus data!"),
2236 };
2237 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2238 data_writes1, arraysize(data_writes1));
2239 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2240
2241 TestCompletionCallback callback;
2242 HttpRequestInfo request1;
2243 request1.method = "GET";
2244 request1.url = GURL("http://www.borked.com/");
2245
2246 std::unique_ptr<HttpTransaction> trans1(
2247 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2248 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
2249 EXPECT_EQ(OK, callback.GetResult(rv));
2250
2251 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2252 ASSERT_TRUE(response1);
2253 ASSERT_TRUE(response1->headers);
2254 EXPECT_EQ(200, response1->headers->response_code());
2255 EXPECT_TRUE(response1->headers->IsKeepAlive());
2256
2257 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2258 // response body.
2259 trans1.reset();
2260
2261 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2262 // socket can't be reused, rather than returning it to the socket pool.
2263 base::RunLoop().RunUntilIdle();
2264
2265 // There should be no idle sockets in the pool.
2266 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2267}
2268
[email protected]038e9a32008-10-08 22:40:162269// Test the request-challenge-retry sequence for basic auth.
2270// (basic auth is the easiest to mock, because it has no randomness).
[email protected]23e482282013-06-14 16:08:022271TEST_P(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422272 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162273 request.method = "GET";
bncce36dca22015-04-21 22:11:232274 request.url = GURL("http://www.example.org/");
[email protected]038e9a32008-10-08 22:40:162275 request.load_flags = 0;
2276
vishal.b62985ca92015-04-17 08:45:512277 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072278 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092279 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2280 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412281 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272282
[email protected]f9ee6b52008-11-08 06:46:232283 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232284 MockWrite(
2285 "GET / HTTP/1.1\r\n"
2286 "Host: www.example.org\r\n"
2287 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232288 };
2289
[email protected]038e9a32008-10-08 22:40:162290 MockRead data_reads1[] = {
2291 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2292 // Give a couple authenticate options (only the middle one is actually
2293 // supported).
[email protected]22927ad2009-09-21 19:56:192294 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162295 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2296 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2297 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2298 // Large content-length -- won't matter, as connection will be reset.
2299 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062300 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162301 };
2302
2303 // After calling trans->RestartWithAuth(), this is the request we should
2304 // be issuing -- the final header line contains the credentials.
2305 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232306 MockWrite(
2307 "GET / HTTP/1.1\r\n"
2308 "Host: www.example.org\r\n"
2309 "Connection: keep-alive\r\n"
2310 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162311 };
2312
2313 // Lastly, the server responds with the actual content.
2314 MockRead data_reads2[] = {
2315 MockRead("HTTP/1.0 200 OK\r\n"),
2316 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2317 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062318 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162319 };
2320
[email protected]31a2bfe2010-02-09 08:03:392321 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2322 data_writes1, arraysize(data_writes1));
2323 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2324 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072325 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2326 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162327
[email protected]49639fa2011-12-20 23:22:412328 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162329
[email protected]49639fa2011-12-20 23:22:412330 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422331 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:162332
2333 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422334 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:162335
[email protected]58e32bb2013-01-21 18:23:252336 LoadTimingInfo load_timing_info1;
2337 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2338 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2339
sclittlefb249892015-09-10 21:33:222340 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
2341 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
2342 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
[email protected]b8015c42013-12-24 15:18:192343 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
2344
[email protected]1c773ea12009-04-28 19:58:422345 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522346 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042347 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162348
[email protected]49639fa2011-12-20 23:22:412349 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162350
[email protected]49639fa2011-12-20 23:22:412351 rv = trans->RestartWithAuth(
2352 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422353 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:162354
2355 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422356 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:162357
[email protected]58e32bb2013-01-21 18:23:252358 LoadTimingInfo load_timing_info2;
2359 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2360 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2361 // The load timing after restart should have a new socket ID, and times after
2362 // those of the first load timing.
2363 EXPECT_LE(load_timing_info1.receive_headers_end,
2364 load_timing_info2.connect_timing.connect_start);
2365 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2366
sclittlefb249892015-09-10 21:33:222367 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
2368 EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
2369 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
[email protected]b8015c42013-12-24 15:18:192370 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
2371
[email protected]038e9a32008-10-08 22:40:162372 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522373 ASSERT_TRUE(response);
2374 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162375 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162376}
2377
ttuttled9dbc652015-09-29 20:00:592378// Test the request-challenge-retry sequence for basic auth.
2379// (basic auth is the easiest to mock, because it has no randomness).
2380TEST_P(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
2381 HttpRequestInfo request;
2382 request.method = "GET";
2383 request.url = GURL("http://www.example.org/");
2384 request.load_flags = 0;
2385
2386 TestNetLog log;
2387 MockHostResolver* resolver = new MockHostResolver();
2388 session_deps_.net_log = &log;
2389 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092390 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
2391 std::unique_ptr<HttpTransaction> trans(
ttuttled9dbc652015-09-29 20:00:592392 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2393
2394 resolver->rules()->ClearRules();
2395 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2396
2397 MockWrite data_writes1[] = {
2398 MockWrite("GET / HTTP/1.1\r\n"
2399 "Host: www.example.org\r\n"
2400 "Connection: keep-alive\r\n\r\n"),
2401 };
2402
2403 MockRead data_reads1[] = {
2404 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2405 // Give a couple authenticate options (only the middle one is actually
2406 // supported).
2407 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2408 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2409 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2410 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2411 // Large content-length -- won't matter, as connection will be reset.
2412 MockRead("Content-Length: 10000\r\n\r\n"),
2413 MockRead(SYNCHRONOUS, ERR_FAILED),
2414 };
2415
2416 // After calling trans->RestartWithAuth(), this is the request we should
2417 // be issuing -- the final header line contains the credentials.
2418 MockWrite data_writes2[] = {
2419 MockWrite("GET / HTTP/1.1\r\n"
2420 "Host: www.example.org\r\n"
2421 "Connection: keep-alive\r\n"
2422 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2423 };
2424
2425 // Lastly, the server responds with the actual content.
2426 MockRead data_reads2[] = {
2427 MockRead("HTTP/1.0 200 OK\r\n"),
2428 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2429 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2430 };
2431
2432 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2433 data_writes1, arraysize(data_writes1));
2434 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2435 data_writes2, arraysize(data_writes2));
2436 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2437 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2438
2439 TestCompletionCallback callback1;
2440
2441 EXPECT_EQ(OK, callback1.GetResult(trans->Start(&request, callback1.callback(),
2442 BoundNetLog())));
2443
2444 LoadTimingInfo load_timing_info1;
2445 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2446 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2447
2448 int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1));
2449 EXPECT_EQ(writes_size1, trans->GetTotalSentBytes());
2450 int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1));
2451 EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
2452
2453 const HttpResponseInfo* response = trans->GetResponseInfo();
2454 ASSERT_TRUE(response);
2455 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2456
2457 IPEndPoint endpoint;
2458 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
2459 ASSERT_FALSE(endpoint.address().empty());
2460 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2461
2462 resolver->rules()->ClearRules();
2463 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2464
2465 TestCompletionCallback callback2;
2466
2467 EXPECT_EQ(OK, callback2.GetResult(trans->RestartWithAuth(
2468 AuthCredentials(kFoo, kBar), callback2.callback())));
2469
2470 LoadTimingInfo load_timing_info2;
2471 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2472 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2473 // The load timing after restart should have a new socket ID, and times after
2474 // those of the first load timing.
2475 EXPECT_LE(load_timing_info1.receive_headers_end,
2476 load_timing_info2.connect_timing.connect_start);
2477 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2478
2479 int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2));
2480 EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes());
2481 int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2));
2482 EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
2483
2484 response = trans->GetResponseInfo();
2485 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522486 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592487 EXPECT_EQ(100, response->headers->GetContentLength());
2488
2489 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
2490 ASSERT_FALSE(endpoint.address().empty());
2491 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2492}
2493
[email protected]23e482282013-06-14 16:08:022494TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462495 HttpRequestInfo request;
2496 request.method = "GET";
bncce36dca22015-04-21 22:11:232497 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292498 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]861fcd52009-08-26 02:33:462499
danakj1fd259a02016-04-16 03:17:092500 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2501 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:412502 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:272503
[email protected]861fcd52009-08-26 02:33:462504 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232505 MockWrite(
2506 "GET / HTTP/1.1\r\n"
2507 "Host: www.example.org\r\n"
2508 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462509 };
2510
2511 MockRead data_reads[] = {
2512 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2513 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2514 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2515 // Large content-length -- won't matter, as connection will be reset.
2516 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062517 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462518 };
2519
[email protected]31a2bfe2010-02-09 08:03:392520 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
2521 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:072522 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412523 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462524
[email protected]49639fa2011-12-20 23:22:412525 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]861fcd52009-08-26 02:33:462526 EXPECT_EQ(ERR_IO_PENDING, rv);
2527
2528 rv = callback.WaitForResult();
2529 EXPECT_EQ(0, rv);
2530
sclittlefb249892015-09-10 21:33:222531 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
2532 EXPECT_EQ(writes_size, trans->GetTotalSentBytes());
2533 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
[email protected]b8015c42013-12-24 15:18:192534 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2535
[email protected]861fcd52009-08-26 02:33:462536 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522537 ASSERT_TRUE(response);
2538 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462539}
2540
[email protected]2d2697f92009-02-18 21:00:322541// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2542// connection.
[email protected]23e482282013-06-14 16:08:022543TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182544 // On the second pass, the body read of the auth challenge is synchronous, so
2545 // IsConnectedAndIdle returns false. The socket should still be drained and
2546 // reused. See http://crbug.com/544255.
2547 for (int i = 0; i < 2; ++i) {
2548 HttpRequestInfo request;
2549 request.method = "GET";
2550 request.url = GURL("http://www.example.org/");
2551 request.load_flags = 0;
[email protected]2d2697f92009-02-18 21:00:322552
mmenkecc2298e2015-12-07 18:20:182553 TestNetLog log;
2554 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092555 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272556
mmenkecc2298e2015-12-07 18:20:182557 MockWrite data_writes[] = {
2558 MockWrite(ASYNC, 0,
2559 "GET / HTTP/1.1\r\n"
2560 "Host: www.example.org\r\n"
2561 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322562
mmenkecc2298e2015-12-07 18:20:182563 // After calling trans->RestartWithAuth(), this is the request we should
2564 // be issuing -- the final header line contains the credentials.
2565 MockWrite(ASYNC, 6,
2566 "GET / HTTP/1.1\r\n"
2567 "Host: www.example.org\r\n"
2568 "Connection: keep-alive\r\n"
2569 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2570 };
[email protected]2d2697f92009-02-18 21:00:322571
mmenkecc2298e2015-12-07 18:20:182572 MockRead data_reads[] = {
2573 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2574 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2575 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2576 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2577 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322578
mmenkecc2298e2015-12-07 18:20:182579 // Lastly, the server responds with the actual content.
2580 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2581 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2582 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2583 MockRead(ASYNC, 10, "Hello"),
2584 };
[email protected]2d2697f92009-02-18 21:00:322585
mmenkecc2298e2015-12-07 18:20:182586 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
2587 arraysize(data_writes));
2588 data.set_busy_before_sync_reads(true);
2589 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462590
mmenkecc2298e2015-12-07 18:20:182591 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322592
danakj1fd259a02016-04-16 03:17:092593 std::unique_ptr<HttpTransaction> trans(
mmenkecc2298e2015-12-07 18:20:182594 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2595 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
2596 ASSERT_EQ(OK, callback1.GetResult(rv));
[email protected]2d2697f92009-02-18 21:00:322597
mmenkecc2298e2015-12-07 18:20:182598 LoadTimingInfo load_timing_info1;
2599 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
2600 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322601
mmenkecc2298e2015-12-07 18:20:182602 const HttpResponseInfo* response = trans->GetResponseInfo();
2603 ASSERT_TRUE(response);
2604 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322605
mmenkecc2298e2015-12-07 18:20:182606 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252607
mmenkecc2298e2015-12-07 18:20:182608 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
2609 callback2.callback());
2610 ASSERT_EQ(OK, callback2.GetResult(rv));
[email protected]2d2697f92009-02-18 21:00:322611
mmenkecc2298e2015-12-07 18:20:182612 LoadTimingInfo load_timing_info2;
2613 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
2614 TestLoadTimingReused(load_timing_info2);
2615 // The load timing after restart should have the same socket ID, and times
2616 // those of the first load timing.
2617 EXPECT_LE(load_timing_info1.receive_headers_end,
2618 load_timing_info2.send_start);
2619 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322620
mmenkecc2298e2015-12-07 18:20:182621 response = trans->GetResponseInfo();
2622 ASSERT_TRUE(response);
2623 EXPECT_FALSE(response->auth_challenge);
2624 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322625
mmenkecc2298e2015-12-07 18:20:182626 std::string response_data;
2627 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]2d2697f92009-02-18 21:00:322628
mmenkecc2298e2015-12-07 18:20:182629 int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes));
2630 EXPECT_EQ(writes_size, trans->GetTotalSentBytes());
2631 int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads));
2632 EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
2633 }
[email protected]2d2697f92009-02-18 21:00:322634}
2635
2636// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2637// connection and with no response body to drain.
[email protected]23e482282013-06-14 16:08:022638TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422639 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322640 request.method = "GET";
bncce36dca22015-04-21 22:11:232641 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322642 request.load_flags = 0;
2643
danakj1fd259a02016-04-16 03:17:092644 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272645
[email protected]2d2697f92009-02-18 21:00:322646 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232647 MockWrite(
2648 "GET / HTTP/1.1\r\n"
2649 "Host: www.example.org\r\n"
2650 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322651
bncce36dca22015-04-21 22:11:232652 // After calling trans->RestartWithAuth(), this is the request we should
2653 // be issuing -- the final header line contains the credentials.
2654 MockWrite(
2655 "GET / HTTP/1.1\r\n"
2656 "Host: www.example.org\r\n"
2657 "Connection: keep-alive\r\n"
2658 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322659 };
2660
[email protected]2d2697f92009-02-18 21:00:322661 MockRead data_reads1[] = {
2662 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2663 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312664 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322665
2666 // Lastly, the server responds with the actual content.
2667 MockRead("HTTP/1.1 200 OK\r\n"),
2668 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502669 MockRead("Content-Length: 5\r\n\r\n"),
2670 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322671 };
2672
[email protected]2d0a4f92011-05-05 16:38:462673 // An incorrect reconnect would cause this to be read.
2674 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062675 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462676 };
2677
[email protected]31a2bfe2010-02-09 08:03:392678 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2679 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462680 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2681 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072682 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2683 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322684
[email protected]49639fa2011-12-20 23:22:412685 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322686
danakj1fd259a02016-04-16 03:17:092687 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502688 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412689 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422690 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322691
2692 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422693 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322694
[email protected]1c773ea12009-04-28 19:58:422695 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522696 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042697 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322698
[email protected]49639fa2011-12-20 23:22:412699 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322700
[email protected]49639fa2011-12-20 23:22:412701 rv = trans->RestartWithAuth(
2702 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422703 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322704
2705 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422706 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322707
2708 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522709 ASSERT_TRUE(response);
2710 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502711 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322712}
2713
2714// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2715// connection and with a large response body to drain.
[email protected]23e482282013-06-14 16:08:022716TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422717 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322718 request.method = "GET";
bncce36dca22015-04-21 22:11:232719 request.url = GURL("http://www.example.org/");
[email protected]2d2697f92009-02-18 21:00:322720 request.load_flags = 0;
2721
danakj1fd259a02016-04-16 03:17:092722 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272723
[email protected]2d2697f92009-02-18 21:00:322724 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232725 MockWrite(
2726 "GET / HTTP/1.1\r\n"
2727 "Host: www.example.org\r\n"
2728 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322729
bncce36dca22015-04-21 22:11:232730 // After calling trans->RestartWithAuth(), this is the request we should
2731 // be issuing -- the final header line contains the credentials.
2732 MockWrite(
2733 "GET / HTTP/1.1\r\n"
2734 "Host: www.example.org\r\n"
2735 "Connection: keep-alive\r\n"
2736 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322737 };
2738
2739 // Respond with 5 kb of response body.
2740 std::string large_body_string("Unauthorized");
2741 large_body_string.append(5 * 1024, ' ');
2742 large_body_string.append("\r\n");
2743
2744 MockRead data_reads1[] = {
2745 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2746 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2747 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2748 // 5134 = 12 + 5 * 1024 + 2
2749 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062750 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322751
2752 // Lastly, the server responds with the actual content.
2753 MockRead("HTTP/1.1 200 OK\r\n"),
2754 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502755 MockRead("Content-Length: 5\r\n\r\n"),
2756 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322757 };
2758
[email protected]2d0a4f92011-05-05 16:38:462759 // An incorrect reconnect would cause this to be read.
2760 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062761 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462762 };
2763
[email protected]31a2bfe2010-02-09 08:03:392764 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2765 data_writes1, arraysize(data_writes1));
[email protected]2d0a4f92011-05-05 16:38:462766 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2767 NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:072768 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2769 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322770
[email protected]49639fa2011-12-20 23:22:412771 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322772
danakj1fd259a02016-04-16 03:17:092773 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502774 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412775 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:422776 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322777
2778 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422779 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322780
[email protected]1c773ea12009-04-28 19:58:422781 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522782 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042783 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322784
[email protected]49639fa2011-12-20 23:22:412785 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322786
[email protected]49639fa2011-12-20 23:22:412787 rv = trans->RestartWithAuth(
2788 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:422789 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]2d2697f92009-02-18 21:00:322790
2791 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:422792 EXPECT_EQ(OK, rv);
[email protected]2d2697f92009-02-18 21:00:322793
2794 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522795 ASSERT_TRUE(response);
2796 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502797 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322798}
2799
2800// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312801// connection, but the server gets impatient and closes the connection.
[email protected]23e482282013-06-14 16:08:022802TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312803 HttpRequestInfo request;
2804 request.method = "GET";
bncce36dca22015-04-21 22:11:232805 request.url = GURL("http://www.example.org/");
[email protected]11203f012009-11-12 23:02:312806 request.load_flags = 0;
2807
danakj1fd259a02016-04-16 03:17:092808 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272809
[email protected]11203f012009-11-12 23:02:312810 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232811 MockWrite(
2812 "GET / HTTP/1.1\r\n"
2813 "Host: www.example.org\r\n"
2814 "Connection: keep-alive\r\n\r\n"),
2815 // This simulates the seemingly successful write to a closed connection
2816 // if the bug is not fixed.
2817 MockWrite(
2818 "GET / HTTP/1.1\r\n"
2819 "Host: www.example.org\r\n"
2820 "Connection: keep-alive\r\n"
2821 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312822 };
2823
2824 MockRead data_reads1[] = {
2825 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2826 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2827 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2828 MockRead("Content-Length: 14\r\n\r\n"),
2829 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062830 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312831 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062832 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312833 };
2834
2835 // After calling trans->RestartWithAuth(), this is the request we should
2836 // be issuing -- the final header line contains the credentials.
2837 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232838 MockWrite(
2839 "GET / HTTP/1.1\r\n"
2840 "Host: www.example.org\r\n"
2841 "Connection: keep-alive\r\n"
2842 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312843 };
2844
2845 // Lastly, the server responds with the actual content.
2846 MockRead data_reads2[] = {
2847 MockRead("HTTP/1.1 200 OK\r\n"),
2848 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502849 MockRead("Content-Length: 5\r\n\r\n"),
2850 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:312851 };
2852
[email protected]31a2bfe2010-02-09 08:03:392853 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2854 data_writes1, arraysize(data_writes1));
2855 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2856 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:072857 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2858 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:312859
[email protected]49639fa2011-12-20 23:22:412860 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:312861
danakj1fd259a02016-04-16 03:17:092862 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:502863 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:412864 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]11203f012009-11-12 23:02:312865 EXPECT_EQ(ERR_IO_PENDING, rv);
2866
2867 rv = callback1.WaitForResult();
2868 EXPECT_EQ(OK, rv);
2869
2870 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522871 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042872 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:312873
[email protected]49639fa2011-12-20 23:22:412874 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:312875
[email protected]49639fa2011-12-20 23:22:412876 rv = trans->RestartWithAuth(
2877 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]11203f012009-11-12 23:02:312878 EXPECT_EQ(ERR_IO_PENDING, rv);
2879
2880 rv = callback2.WaitForResult();
2881 EXPECT_EQ(OK, rv);
2882
2883 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522884 ASSERT_TRUE(response);
2885 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502886 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:312887}
2888
[email protected]394816e92010-08-03 07:38:592889// Test the request-challenge-retry sequence for basic auth, over a connection
2890// that requires a restart when setting up an SSL tunnel.
ttuttle34f63b52015-03-05 04:33:012891TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
2892 HttpRequestInfo request;
2893 request.method = "GET";
bncce36dca22015-04-21 22:11:232894 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:012895 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:292896 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:012897
2898 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:032899 session_deps_.proxy_service =
2900 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:512901 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:012902 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:092903 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:012904
2905 // Since we have proxy, should try to establish tunnel.
2906 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:542907 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172908 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542909 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:012910 };
2911
mmenkee71e15332015-10-07 16:39:542912 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:012913 // connection.
2914 MockRead data_reads1[] = {
2915 // No credentials.
2916 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
2917 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:542918 };
ttuttle34f63b52015-03-05 04:33:012919
mmenkee71e15332015-10-07 16:39:542920 // Since the first connection couldn't be reused, need to establish another
2921 // once given credentials.
2922 MockWrite data_writes2[] = {
2923 // After calling trans->RestartWithAuth(), this is the request we should
2924 // be issuing -- the final header line contains the credentials.
2925 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:172926 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:542927 "Proxy-Connection: keep-alive\r\n"
2928 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2929
2930 MockWrite("GET / HTTP/1.1\r\n"
2931 "Host: www.example.org\r\n"
2932 "Connection: keep-alive\r\n\r\n"),
2933 };
2934
2935 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:012936 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
2937
2938 MockRead("HTTP/1.1 200 OK\r\n"),
2939 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2940 MockRead("Content-Length: 5\r\n\r\n"),
2941 MockRead(SYNCHRONOUS, "hello"),
2942 };
2943
2944 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
2945 data_writes1, arraysize(data_writes1));
2946 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:542947 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
2948 data_writes2, arraysize(data_writes2));
2949 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:012950 SSLSocketDataProvider ssl(ASYNC, OK);
2951 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
2952
2953 TestCompletionCallback callback1;
2954
danakj1fd259a02016-04-16 03:17:092955 std::unique_ptr<HttpTransaction> trans(
ttuttle34f63b52015-03-05 04:33:012956 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
2957
2958 int rv = trans->Start(&request, callback1.callback(), log.bound());
2959 EXPECT_EQ(ERR_IO_PENDING, rv);
2960
2961 rv = callback1.WaitForResult();
2962 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:462963 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:012964 log.GetEntries(&entries);
2965 size_t pos = ExpectLogContainsSomewhere(
2966 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
2967 NetLog::PHASE_NONE);
2968 ExpectLogContainsSomewhere(
2969 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
2970 NetLog::PHASE_NONE);
2971
2972 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522973 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012974 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:522975 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:012976 EXPECT_EQ(407, response->headers->response_code());
2977 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
2978 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
2979
2980 LoadTimingInfo load_timing_info;
2981 // CONNECT requests and responses are handled at the connect job level, so
2982 // the transaction does not yet have a connection.
2983 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
2984
2985 TestCompletionCallback callback2;
2986
2987 rv =
2988 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
2989 EXPECT_EQ(ERR_IO_PENDING, rv);
2990
2991 rv = callback2.WaitForResult();
2992 EXPECT_EQ(OK, rv);
2993
2994 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:522995 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:012996
2997 EXPECT_TRUE(response->headers->IsKeepAlive());
2998 EXPECT_EQ(200, response->headers->response_code());
2999 EXPECT_EQ(5, response->headers->GetContentLength());
3000 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3001
3002 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523003 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013004
3005 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3006 TestLoadTimingNotReusedWithPac(load_timing_info,
3007 CONNECT_TIMING_HAS_SSL_TIMES);
3008
3009 trans.reset();
3010 session->CloseAllConnections();
3011}
3012
3013// Test the request-challenge-retry sequence for basic auth, over a connection
3014// that requires a restart when setting up an SSL tunnel.
3015TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593016 HttpRequestInfo request;
3017 request.method = "GET";
bncce36dca22015-04-21 22:11:233018 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593019 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293020 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]394816e92010-08-03 07:38:593021
[email protected]cb9bf6ca2011-01-28 13:15:273022 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033023 session_deps_.proxy_service =
3024 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513025 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073026 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093027 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273028
[email protected]394816e92010-08-03 07:38:593029 // Since we have proxy, should try to establish tunnel.
3030 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543031 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173032 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543033 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113034 };
3035
mmenkee71e15332015-10-07 16:39:543036 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083037 // connection.
3038 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543039 // No credentials.
3040 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3041 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3042 MockRead("Proxy-Connection: close\r\n\r\n"),
3043 };
mmenkee0b5c882015-08-26 20:29:113044
mmenkee71e15332015-10-07 16:39:543045 MockWrite data_writes2[] = {
3046 // After calling trans->RestartWithAuth(), this is the request we should
3047 // be issuing -- the final header line contains the credentials.
3048 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173049 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543050 "Proxy-Connection: keep-alive\r\n"
3051 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083052
mmenkee71e15332015-10-07 16:39:543053 MockWrite("GET / HTTP/1.1\r\n"
3054 "Host: www.example.org\r\n"
3055 "Connection: keep-alive\r\n\r\n"),
3056 };
3057
3058 MockRead data_reads2[] = {
3059 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3060
3061 MockRead("HTTP/1.1 200 OK\r\n"),
3062 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3063 MockRead("Content-Length: 5\r\n\r\n"),
3064 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593065 };
3066
3067 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3068 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073069 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenkee71e15332015-10-07 16:39:543070 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3071 data_writes2, arraysize(data_writes2));
3072 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063073 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073074 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593075
[email protected]49639fa2011-12-20 23:22:413076 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593077
danakj1fd259a02016-04-16 03:17:093078 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503079 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:503080
[email protected]49639fa2011-12-20 23:22:413081 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]394816e92010-08-03 07:38:593082 EXPECT_EQ(ERR_IO_PENDING, rv);
3083
3084 rv = callback1.WaitForResult();
3085 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:463086 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403087 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593088 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403089 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]394816e92010-08-03 07:38:593090 NetLog::PHASE_NONE);
3091 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403092 entries, pos,
[email protected]394816e92010-08-03 07:38:593093 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3094 NetLog::PHASE_NONE);
3095
3096 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523097 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013098 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523099 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593100 EXPECT_EQ(407, response->headers->response_code());
3101 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043102 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593103
[email protected]029c83b62013-01-24 05:28:203104 LoadTimingInfo load_timing_info;
3105 // CONNECT requests and responses are handled at the connect job level, so
3106 // the transaction does not yet have a connection.
3107 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3108
[email protected]49639fa2011-12-20 23:22:413109 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593110
[email protected]49639fa2011-12-20 23:22:413111 rv = trans->RestartWithAuth(
3112 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]394816e92010-08-03 07:38:593113 EXPECT_EQ(ERR_IO_PENDING, rv);
3114
3115 rv = callback2.WaitForResult();
3116 EXPECT_EQ(OK, rv);
3117
3118 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523119 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593120
3121 EXPECT_TRUE(response->headers->IsKeepAlive());
3122 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503123 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593124 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3125
3126 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523127 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503128
[email protected]029c83b62013-01-24 05:28:203129 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3130 TestLoadTimingNotReusedWithPac(load_timing_info,
3131 CONNECT_TIMING_HAS_SSL_TIMES);
3132
[email protected]0b0bf032010-09-21 18:08:503133 trans.reset();
[email protected]102e27c2011-02-23 01:01:313134 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593135}
3136
[email protected]11203f012009-11-12 23:02:313137// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013138// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
3139TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233140 // On the second pass, the body read of the auth challenge is synchronous, so
3141 // IsConnectedAndIdle returns false. The socket should still be drained and
3142 // reused. See http://crbug.com/544255.
3143 for (int i = 0; i < 2; ++i) {
3144 HttpRequestInfo request;
3145 request.method = "GET";
3146 request.url = GURL("https://www.example.org/");
3147 // Ensure that proxy authentication is attempted even
3148 // when the no authentication data flag is set.
3149 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
ttuttle34f63b52015-03-05 04:33:013150
mmenked39192ee2015-12-09 00:57:233151 // Configure against proxy server "myproxy:70".
3152 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3153 BoundTestNetLog log;
3154 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093155 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013156
danakj1fd259a02016-04-16 03:17:093157 std::unique_ptr<HttpTransaction> trans(
mmenked39192ee2015-12-09 00:57:233158 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
ttuttle34f63b52015-03-05 04:33:013159
mmenked39192ee2015-12-09 00:57:233160 // Since we have proxy, should try to establish tunnel.
3161 MockWrite data_writes1[] = {
3162 MockWrite(ASYNC, 0,
3163 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3164 "Host: www.example.org:443\r\n"
3165 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013166
mmenked39192ee2015-12-09 00:57:233167 // After calling trans->RestartWithAuth(), this is the request we should
3168 // be issuing -- the final header line contains the credentials.
3169 MockWrite(ASYNC, 3,
3170 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3171 "Host: www.example.org:443\r\n"
3172 "Proxy-Connection: keep-alive\r\n"
3173 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3174 };
ttuttle34f63b52015-03-05 04:33:013175
mmenked39192ee2015-12-09 00:57:233176 // The proxy responds to the connect with a 407, using a persistent
3177 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3178 MockRead data_reads1[] = {
3179 // No credentials.
3180 MockRead(ASYNC, 1,
3181 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3182 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3183 "Proxy-Connection: keep-alive\r\n"
3184 "Content-Length: 10\r\n\r\n"),
3185 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013186
mmenked39192ee2015-12-09 00:57:233187 // Wrong credentials (wrong password).
3188 MockRead(ASYNC, 4,
3189 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3190 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3191 "Proxy-Connection: keep-alive\r\n"
3192 "Content-Length: 10\r\n\r\n"),
3193 // No response body because the test stops reading here.
3194 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3195 };
ttuttle34f63b52015-03-05 04:33:013196
mmenked39192ee2015-12-09 00:57:233197 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3198 arraysize(data_writes1));
3199 data1.set_busy_before_sync_reads(true);
3200 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013201
mmenked39192ee2015-12-09 00:57:233202 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013203
mmenked39192ee2015-12-09 00:57:233204 int rv = trans->Start(&request, callback1.callback(), log.bound());
3205 EXPECT_EQ(OK, callback1.GetResult(rv));
ttuttle34f63b52015-03-05 04:33:013206
mmenked39192ee2015-12-09 00:57:233207 TestNetLogEntry::List entries;
3208 log.GetEntries(&entries);
3209 size_t pos = ExpectLogContainsSomewhere(
3210 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3211 NetLog::PHASE_NONE);
3212 ExpectLogContainsSomewhere(
3213 entries, pos,
3214 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3215 NetLog::PHASE_NONE);
ttuttle34f63b52015-03-05 04:33:013216
mmenked39192ee2015-12-09 00:57:233217 const HttpResponseInfo* response = trans->GetResponseInfo();
3218 ASSERT_TRUE(response);
3219 ASSERT_TRUE(response->headers);
3220 EXPECT_TRUE(response->headers->IsKeepAlive());
3221 EXPECT_EQ(407, response->headers->response_code());
3222 EXPECT_EQ(10, response->headers->GetContentLength());
3223 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3224 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013225
mmenked39192ee2015-12-09 00:57:233226 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013227
mmenked39192ee2015-12-09 00:57:233228 // Wrong password (should be "bar").
3229 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBaz),
3230 callback2.callback());
3231 EXPECT_EQ(OK, callback2.GetResult(rv));
ttuttle34f63b52015-03-05 04:33:013232
mmenked39192ee2015-12-09 00:57:233233 response = trans->GetResponseInfo();
3234 ASSERT_TRUE(response);
3235 ASSERT_TRUE(response->headers);
3236 EXPECT_TRUE(response->headers->IsKeepAlive());
3237 EXPECT_EQ(407, response->headers->response_code());
3238 EXPECT_EQ(10, response->headers->GetContentLength());
3239 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3240 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013241
mmenked39192ee2015-12-09 00:57:233242 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3243 // out of scope.
3244 session->CloseAllConnections();
3245 }
ttuttle34f63b52015-03-05 04:33:013246}
3247
3248// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3249// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
3250TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233251 // On the second pass, the body read of the auth challenge is synchronous, so
3252 // IsConnectedAndIdle returns false. The socket should still be drained and
3253 // reused. See http://crbug.com/544255.
3254 for (int i = 0; i < 2; ++i) {
3255 HttpRequestInfo request;
3256 request.method = "GET";
3257 request.url = GURL("https://www.example.org/");
3258 // Ensure that proxy authentication is attempted even
3259 // when the no authentication data flag is set.
3260 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3261
3262 // Configure against proxy server "myproxy:70".
3263 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
3264 BoundTestNetLog log;
3265 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093266 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233267
danakj1fd259a02016-04-16 03:17:093268 std::unique_ptr<HttpTransaction> trans(
mmenked39192ee2015-12-09 00:57:233269 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3270
3271 // Since we have proxy, should try to establish tunnel.
3272 MockWrite data_writes1[] = {
3273 MockWrite(ASYNC, 0,
3274 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3275 "Host: www.example.org:443\r\n"
3276 "Proxy-Connection: keep-alive\r\n\r\n"),
3277
3278 // After calling trans->RestartWithAuth(), this is the request we should
3279 // be issuing -- the final header line contains the credentials.
3280 MockWrite(ASYNC, 3,
3281 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3282 "Host: www.example.org:443\r\n"
3283 "Proxy-Connection: keep-alive\r\n"
3284 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3285 };
3286
3287 // The proxy responds to the connect with a 407, using a persistent
3288 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3289 MockRead data_reads1[] = {
3290 // No credentials.
3291 MockRead(ASYNC, 1,
3292 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3293 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3294 "Content-Length: 10\r\n\r\n"),
3295 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3296
3297 // Wrong credentials (wrong password).
3298 MockRead(ASYNC, 4,
3299 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3300 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3301 "Content-Length: 10\r\n\r\n"),
3302 // No response body because the test stops reading here.
3303 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3304 };
3305
3306 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3307 arraysize(data_writes1));
3308 data1.set_busy_before_sync_reads(true);
3309 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3310
3311 TestCompletionCallback callback1;
3312
3313 int rv = trans->Start(&request, callback1.callback(), log.bound());
3314 EXPECT_EQ(OK, callback1.GetResult(rv));
3315
3316 TestNetLogEntry::List entries;
3317 log.GetEntries(&entries);
3318 size_t pos = ExpectLogContainsSomewhere(
3319 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3320 NetLog::PHASE_NONE);
3321 ExpectLogContainsSomewhere(
3322 entries, pos,
3323 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3324 NetLog::PHASE_NONE);
3325
3326 const HttpResponseInfo* response = trans->GetResponseInfo();
3327 ASSERT_TRUE(response);
3328 ASSERT_TRUE(response->headers);
3329 EXPECT_TRUE(response->headers->IsKeepAlive());
3330 EXPECT_EQ(407, response->headers->response_code());
3331 EXPECT_EQ(10, response->headers->GetContentLength());
3332 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3333 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3334
3335 TestCompletionCallback callback2;
3336
3337 // Wrong password (should be "bar").
3338 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBaz),
3339 callback2.callback());
3340 EXPECT_EQ(OK, callback2.GetResult(rv));
3341
3342 response = trans->GetResponseInfo();
3343 ASSERT_TRUE(response);
3344 ASSERT_TRUE(response->headers);
3345 EXPECT_TRUE(response->headers->IsKeepAlive());
3346 EXPECT_EQ(407, response->headers->response_code());
3347 EXPECT_EQ(10, response->headers->GetContentLength());
3348 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3349 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3350
3351 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3352 // out of scope.
3353 session->CloseAllConnections();
3354 }
3355}
3356
3357// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3358// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3359// the case the server sends extra data on the original socket, so it can't be
3360// reused.
3361TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273362 HttpRequestInfo request;
3363 request.method = "GET";
bncce36dca22015-04-21 22:11:233364 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273365 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293366 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]cb9bf6ca2011-01-28 13:15:273367
[email protected]2d2697f92009-02-18 21:00:323368 // Configure against proxy server "myproxy:70".
mmenked39192ee2015-12-09 00:57:233369 session_deps_.proxy_service =
3370 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:513371 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073372 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093373 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323374
[email protected]2d2697f92009-02-18 21:00:323375 // Since we have proxy, should try to establish tunnel.
3376 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233377 MockWrite(ASYNC, 0,
3378 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173379 "Host: www.example.org:443\r\n"
3380 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233381 };
[email protected]2d2697f92009-02-18 21:00:323382
mmenked39192ee2015-12-09 00:57:233383 // The proxy responds to the connect with a 407, using a persistent, but sends
3384 // extra data, so the socket cannot be reused.
3385 MockRead data_reads1[] = {
3386 // No credentials.
3387 MockRead(ASYNC, 1,
3388 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3389 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3390 "Content-Length: 10\r\n\r\n"),
3391 MockRead(SYNCHRONOUS, 2, "0123456789"),
3392 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3393 };
3394
3395 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233396 // After calling trans->RestartWithAuth(), this is the request we should
3397 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233398 MockWrite(ASYNC, 0,
3399 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173400 "Host: www.example.org:443\r\n"
3401 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233402 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3403
3404 MockWrite(ASYNC, 2,
3405 "GET / HTTP/1.1\r\n"
3406 "Host: www.example.org\r\n"
3407 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323408 };
3409
mmenked39192ee2015-12-09 00:57:233410 MockRead data_reads2[] = {
3411 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323412
mmenked39192ee2015-12-09 00:57:233413 MockRead(ASYNC, 3,
3414 "HTTP/1.1 200 OK\r\n"
3415 "Content-Type: text/html; charset=iso-8859-1\r\n"
3416 "Content-Length: 5\r\n\r\n"),
3417 // No response body because the test stops reading here.
3418 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323419 };
3420
mmenked39192ee2015-12-09 00:57:233421 SequencedSocketData data1(data_reads1, arraysize(data_reads1), data_writes1,
3422 arraysize(data_writes1));
3423 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073424 session_deps_.socket_factory->AddSocketDataProvider(&data1);
mmenked39192ee2015-12-09 00:57:233425 SequencedSocketData data2(data_reads2, arraysize(data_reads2), data_writes2,
3426 arraysize(data_writes2));
3427 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3428 SSLSocketDataProvider ssl(ASYNC, OK);
3429 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323430
[email protected]49639fa2011-12-20 23:22:413431 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323432
danakj1fd259a02016-04-16 03:17:093433 std::unique_ptr<HttpTransaction> trans(
mmenked39192ee2015-12-09 00:57:233434 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d2697f92009-02-18 21:00:323435
mmenked39192ee2015-12-09 00:57:233436 int rv = trans->Start(&request, callback1.callback(), log.bound());
3437 EXPECT_EQ(OK, callback1.GetResult(rv));
3438
mmenke43758e62015-05-04 21:09:463439 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403440 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393441 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403442 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]dbb83db2010-05-11 18:13:393443 NetLog::PHASE_NONE);
3444 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403445 entries, pos,
[email protected]dbb83db2010-05-11 18:13:393446 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3447 NetLog::PHASE_NONE);
[email protected]2d2697f92009-02-18 21:00:323448
[email protected]1c773ea12009-04-28 19:58:423449 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243450 ASSERT_TRUE(response);
3451 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323452 EXPECT_TRUE(response->headers->IsKeepAlive());
3453 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423454 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043455 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323456
mmenked39192ee2015-12-09 00:57:233457 LoadTimingInfo load_timing_info;
3458 // CONNECT requests and responses are handled at the connect job level, so
3459 // the transaction does not yet have a connection.
3460 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3461
[email protected]49639fa2011-12-20 23:22:413462 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323463
mmenked39192ee2015-12-09 00:57:233464 rv =
3465 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
3466 EXPECT_EQ(OK, callback2.GetResult(rv));
[email protected]2d2697f92009-02-18 21:00:323467
[email protected]2d2697f92009-02-18 21:00:323468 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233469 EXPECT_EQ(200, response->headers->response_code());
3470 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423471 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133472
mmenked39192ee2015-12-09 00:57:233473 // The password prompt info should not be set.
3474 EXPECT_FALSE(response->auth_challenge);
3475
3476 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3477 TestLoadTimingNotReusedWithPac(load_timing_info,
3478 CONNECT_TIMING_HAS_SSL_TIMES);
3479
3480 trans.reset();
[email protected]102e27c2011-02-23 01:01:313481 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323482}
3483
mmenkee71e15332015-10-07 16:39:543484// Test the case a proxy closes a socket while the challenge body is being
3485// drained.
3486TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
3487 HttpRequestInfo request;
3488 request.method = "GET";
3489 request.url = GURL("https://www.example.org/");
3490 // Ensure that proxy authentication is attempted even
3491 // when the no authentication data flag is set.
3492 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
3493
3494 // Configure against proxy server "myproxy:70".
3495 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:093496 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543497
danakj1fd259a02016-04-16 03:17:093498 std::unique_ptr<HttpTransaction> trans(
mmenkee71e15332015-10-07 16:39:543499 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3500
3501 // Since we have proxy, should try to establish tunnel.
3502 MockWrite data_writes1[] = {
3503 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173504 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543505 "Proxy-Connection: keep-alive\r\n\r\n"),
3506 };
3507
3508 // The proxy responds to the connect with a 407, using a persistent
3509 // connection.
3510 MockRead data_reads1[] = {
3511 // No credentials.
3512 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3513 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3514 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3515 // Server hands up in the middle of the body.
3516 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3517 };
3518
3519 MockWrite data_writes2[] = {
3520 // After calling trans->RestartWithAuth(), this is the request we should
3521 // be issuing -- the final header line contains the credentials.
3522 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173523 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543524 "Proxy-Connection: keep-alive\r\n"
3525 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3526
3527 MockWrite("GET / HTTP/1.1\r\n"
3528 "Host: www.example.org\r\n"
3529 "Connection: keep-alive\r\n\r\n"),
3530 };
3531
3532 MockRead data_reads2[] = {
3533 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3534
3535 MockRead("HTTP/1.1 200 OK\r\n"),
3536 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3537 MockRead("Content-Length: 5\r\n\r\n"),
3538 MockRead(SYNCHRONOUS, "hello"),
3539 };
3540
3541 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3542 data_writes1, arraysize(data_writes1));
3543 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3544 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3545 data_writes2, arraysize(data_writes2));
3546 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3547 SSLSocketDataProvider ssl(ASYNC, OK);
3548 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3549
3550 TestCompletionCallback callback;
3551
3552 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3553 EXPECT_EQ(OK, callback.GetResult(rv));
3554
3555 const HttpResponseInfo* response = trans->GetResponseInfo();
3556 ASSERT_TRUE(response);
3557 ASSERT_TRUE(response->headers);
3558 EXPECT_TRUE(response->headers->IsKeepAlive());
3559 EXPECT_EQ(407, response->headers->response_code());
3560 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3561
3562 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
3563 EXPECT_EQ(OK, callback.GetResult(rv));
3564
3565 response = trans->GetResponseInfo();
3566 ASSERT_TRUE(response);
3567 ASSERT_TRUE(response->headers);
3568 EXPECT_TRUE(response->headers->IsKeepAlive());
3569 EXPECT_EQ(200, response->headers->response_code());
3570 std::string body;
3571 EXPECT_EQ(OK, ReadTransaction(trans.get(), &body));
3572 EXPECT_EQ("hello", body);
3573}
3574
[email protected]a8e9b162009-03-12 00:06:443575// Test that we don't read the response body when we fail to establish a tunnel,
3576// even if the user cancels the proxy's auth attempt.
[email protected]23e482282013-06-14 16:08:023577TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273578 HttpRequestInfo request;
3579 request.method = "GET";
bncce36dca22015-04-21 22:11:233580 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273581 request.load_flags = 0;
3582
[email protected]a8e9b162009-03-12 00:06:443583 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033584 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]a8e9b162009-03-12 00:06:443585
danakj1fd259a02016-04-16 03:17:093586 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443587
danakj1fd259a02016-04-16 03:17:093588 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503589 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]a8e9b162009-03-12 00:06:443590
[email protected]a8e9b162009-03-12 00:06:443591 // Since we have proxy, should try to establish tunnel.
3592 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173593 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3594 "Host: www.example.org:443\r\n"
3595 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443596 };
3597
3598 // The proxy responds to the connect with a 407.
3599 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243600 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3601 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3602 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233603 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243604 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443605 };
3606
[email protected]31a2bfe2010-02-09 08:03:393607 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
3608 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:073609 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443610
[email protected]49639fa2011-12-20 23:22:413611 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443612
[email protected]49639fa2011-12-20 23:22:413613 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:423614 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]a8e9b162009-03-12 00:06:443615
3616 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:423617 EXPECT_EQ(OK, rv);
[email protected]a8e9b162009-03-12 00:06:443618
[email protected]1c773ea12009-04-28 19:58:423619 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243620 ASSERT_TRUE(response);
3621 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443622 EXPECT_TRUE(response->headers->IsKeepAlive());
3623 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423624 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443625
3626 std::string response_data;
3627 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:423628 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]e60e47a2010-07-14 03:37:183629
3630 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313631 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443632}
3633
ttuttle7933c112015-01-06 00:55:243634// Test that we don't pass extraneous headers from the proxy's response to the
3635// caller when the proxy responds to CONNECT with 407.
3636TEST_P(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
3637 HttpRequestInfo request;
3638 request.method = "GET";
bncce36dca22015-04-21 22:11:233639 request.url = GURL("https://www.example.org/");
ttuttle7933c112015-01-06 00:55:243640 request.load_flags = 0;
3641
3642 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:033643 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
ttuttle7933c112015-01-06 00:55:243644
danakj1fd259a02016-04-16 03:17:093645 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243646
danakj1fd259a02016-04-16 03:17:093647 std::unique_ptr<HttpTransaction> trans(
ttuttle7933c112015-01-06 00:55:243648 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3649
3650 // Since we have proxy, should try to establish tunnel.
3651 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173652 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3653 "Host: www.example.org:443\r\n"
3654 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243655 };
3656
3657 // The proxy responds to the connect with a 407.
3658 MockRead data_reads[] = {
3659 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3660 MockRead("X-Foo: bar\r\n"),
3661 MockRead("Set-Cookie: foo=bar\r\n"),
3662 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3663 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233664 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243665 };
3666
3667 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
3668 arraysize(data_writes));
3669 session_deps_.socket_factory->AddSocketDataProvider(&data);
3670
3671 TestCompletionCallback callback;
3672
3673 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3674 EXPECT_EQ(ERR_IO_PENDING, rv);
3675
3676 rv = callback.WaitForResult();
3677 EXPECT_EQ(OK, rv);
3678
3679 const HttpResponseInfo* response = trans->GetResponseInfo();
3680 ASSERT_TRUE(response);
3681 ASSERT_TRUE(response->headers);
3682 EXPECT_TRUE(response->headers->IsKeepAlive());
3683 EXPECT_EQ(407, response->headers->response_code());
3684 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3685 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3686 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3687
3688 std::string response_data;
3689 rv = ReadTransaction(trans.get(), &response_data);
3690 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
3691
3692 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3693 session->CloseAllConnections();
3694}
3695
[email protected]8fdbcd22010-05-05 02:54:523696// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3697// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
[email protected]23e482282013-06-14 16:08:023698TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523699 HttpRequestInfo request;
3700 request.method = "GET";
bncce36dca22015-04-21 22:11:233701 request.url = GURL("http://www.example.org/");
[email protected]8fdbcd22010-05-05 02:54:523702 request.load_flags = 0;
3703
[email protected]cb9bf6ca2011-01-28 13:15:273704 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093705 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
3706 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:413707 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:273708
[email protected]8fdbcd22010-05-05 02:54:523709 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233710 MockWrite(
3711 "GET / HTTP/1.1\r\n"
3712 "Host: www.example.org\r\n"
3713 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523714 };
3715
3716 MockRead data_reads1[] = {
3717 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3718 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3719 // Large content-length -- won't matter, as connection will be reset.
3720 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063721 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523722 };
3723
3724 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3725 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073726 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523727
[email protected]49639fa2011-12-20 23:22:413728 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523729
[email protected]49639fa2011-12-20 23:22:413730 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]8fdbcd22010-05-05 02:54:523731 EXPECT_EQ(ERR_IO_PENDING, rv);
3732
3733 rv = callback.WaitForResult();
3734 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
3735}
3736
[email protected]7a67a8152010-11-05 18:31:103737// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3738// through a non-authenticating proxy. The request should fail with
3739// ERR_UNEXPECTED_PROXY_AUTH.
3740// Note that it is impossible to detect if an HTTP server returns a 407 through
3741// a non-authenticating proxy - there is nothing to indicate whether the
3742// response came from the proxy or the server, so it is treated as if the proxy
3743// issued the challenge.
[email protected]23e482282013-06-14 16:08:023744TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:233745 HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273746 HttpRequestInfo request;
3747 request.method = "GET";
bncce36dca22015-04-21 22:11:233748 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273749
rdsmith82957ad2015-09-16 19:42:033750 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:513751 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073752 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093753 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103754
[email protected]7a67a8152010-11-05 18:31:103755 // Since we have proxy, should try to establish tunnel.
3756 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173757 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3758 "Host: www.example.org:443\r\n"
3759 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103760
rsleevidb16bb02015-11-12 23:47:173761 MockWrite("GET / HTTP/1.1\r\n"
3762 "Host: www.example.org\r\n"
3763 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103764 };
3765
3766 MockRead data_reads1[] = {
3767 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3768
3769 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3770 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3771 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063772 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103773 };
3774
3775 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3776 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:073777 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063778 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073779 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103780
[email protected]49639fa2011-12-20 23:22:413781 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103782
danakj1fd259a02016-04-16 03:17:093783 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:503784 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7a67a8152010-11-05 18:31:103785
[email protected]49639fa2011-12-20 23:22:413786 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7a67a8152010-11-05 18:31:103787 EXPECT_EQ(ERR_IO_PENDING, rv);
3788
3789 rv = callback1.WaitForResult();
3790 EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
mmenke43758e62015-05-04 21:09:463791 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403792 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103793 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403794 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]7a67a8152010-11-05 18:31:103795 NetLog::PHASE_NONE);
3796 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403797 entries, pos,
[email protected]7a67a8152010-11-05 18:31:103798 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3799 NetLog::PHASE_NONE);
3800}
[email protected]2df19bb2010-08-25 20:13:463801
mmenke2a1781d2015-10-07 19:25:333802// Test a proxy auth scheme that allows default credentials and a proxy server
3803// that uses non-persistent connections.
3804TEST_P(HttpNetworkTransactionTest,
3805 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3806 HttpRequestInfo request;
3807 request.method = "GET";
3808 request.url = GURL("https://www.example.org/");
3809
3810 // Configure against proxy server "myproxy:70".
3811 session_deps_.proxy_service =
3812 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3813
danakj1fd259a02016-04-16 03:17:093814 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333815 new HttpAuthHandlerMock::Factory());
3816 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093817 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333818 mock_handler->set_allows_default_credentials(true);
3819 auth_handler_factory->AddMockHandler(mock_handler.release(),
3820 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483821 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333822
3823 // Add NetLog just so can verify load timing information gets a NetLog ID.
3824 NetLog net_log;
3825 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093826 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333827
3828 // Since we have proxy, should try to establish tunnel.
3829 MockWrite data_writes1[] = {
3830 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173831 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333832 "Proxy-Connection: keep-alive\r\n\r\n"),
3833 };
3834
3835 // The proxy responds to the connect with a 407, using a non-persistent
3836 // connection.
3837 MockRead data_reads1[] = {
3838 // No credentials.
3839 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3840 MockRead("Proxy-Authenticate: Mock\r\n"),
3841 MockRead("Proxy-Connection: close\r\n\r\n"),
3842 };
3843
3844 // Since the first connection couldn't be reused, need to establish another
3845 // once given credentials.
3846 MockWrite data_writes2[] = {
3847 // After calling trans->RestartWithAuth(), this is the request we should
3848 // be issuing -- the final header line contains the credentials.
3849 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173850 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333851 "Proxy-Connection: keep-alive\r\n"
3852 "Proxy-Authorization: auth_token\r\n\r\n"),
3853
3854 MockWrite("GET / HTTP/1.1\r\n"
3855 "Host: www.example.org\r\n"
3856 "Connection: keep-alive\r\n\r\n"),
3857 };
3858
3859 MockRead data_reads2[] = {
3860 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3861
3862 MockRead("HTTP/1.1 200 OK\r\n"),
3863 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3864 MockRead("Content-Length: 5\r\n\r\n"),
3865 MockRead(SYNCHRONOUS, "hello"),
3866 };
3867
3868 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3869 data_writes1, arraysize(data_writes1));
3870 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3871 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3872 data_writes2, arraysize(data_writes2));
3873 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3874 SSLSocketDataProvider ssl(ASYNC, OK);
3875 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3876
danakj1fd259a02016-04-16 03:17:093877 std::unique_ptr<HttpTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333878 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3879
3880 TestCompletionCallback callback;
3881 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
3882 EXPECT_EQ(OK, callback.GetResult(rv));
3883
3884 const HttpResponseInfo* response = trans->GetResponseInfo();
3885 ASSERT_TRUE(response);
3886 ASSERT_TRUE(response->headers);
3887 EXPECT_FALSE(response->headers->IsKeepAlive());
3888 EXPECT_EQ(407, response->headers->response_code());
3889 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3890 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:523891 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:333892
3893 LoadTimingInfo load_timing_info;
3894 // CONNECT requests and responses are handled at the connect job level, so
3895 // the transaction does not yet have a connection.
3896 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3897
3898 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
3899 EXPECT_EQ(OK, callback.GetResult(rv));
3900 response = trans->GetResponseInfo();
3901 ASSERT_TRUE(response);
3902 ASSERT_TRUE(response->headers);
3903 EXPECT_TRUE(response->headers->IsKeepAlive());
3904 EXPECT_EQ(200, response->headers->response_code());
3905 EXPECT_EQ(5, response->headers->GetContentLength());
3906 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3907
3908 // The password prompt info should not be set.
3909 EXPECT_FALSE(response->auth_challenge);
3910
3911 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3912 TestLoadTimingNotReusedWithPac(load_timing_info,
3913 CONNECT_TIMING_HAS_SSL_TIMES);
3914
3915 trans.reset();
3916 session->CloseAllConnections();
3917}
3918
3919// Test a proxy auth scheme that allows default credentials and a proxy server
3920// that hangs up when credentials are initially sent.
3921TEST_P(HttpNetworkTransactionTest,
3922 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
3923 HttpRequestInfo request;
3924 request.method = "GET";
3925 request.url = GURL("https://www.example.org/");
3926
3927 // Configure against proxy server "myproxy:70".
3928 session_deps_.proxy_service =
3929 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
3930
danakj1fd259a02016-04-16 03:17:093931 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:333932 new HttpAuthHandlerMock::Factory());
3933 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:093934 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:333935 mock_handler->set_allows_default_credentials(true);
3936 auth_handler_factory->AddMockHandler(mock_handler.release(),
3937 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483938 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333939
3940 // Add NetLog just so can verify load timing information gets a NetLog ID.
3941 NetLog net_log;
3942 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093943 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333944
3945 // Should try to establish tunnel.
3946 MockWrite data_writes1[] = {
3947 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173948 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333949 "Proxy-Connection: keep-alive\r\n\r\n"),
3950
3951 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173952 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333953 "Proxy-Connection: keep-alive\r\n"
3954 "Proxy-Authorization: auth_token\r\n\r\n"),
3955 };
3956
3957 // The proxy responds to the connect with a 407, using a non-persistent
3958 // connection.
3959 MockRead data_reads1[] = {
3960 // No credentials.
3961 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3962 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
3963 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
3964 };
3965
3966 // Since the first connection was closed, need to establish another once given
3967 // credentials.
3968 MockWrite data_writes2[] = {
3969 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173970 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333971 "Proxy-Connection: keep-alive\r\n"
3972 "Proxy-Authorization: auth_token\r\n\r\n"),
3973
3974 MockWrite("GET / HTTP/1.1\r\n"
3975 "Host: www.example.org\r\n"
3976 "Connection: keep-alive\r\n\r\n"),
3977 };
3978
3979 MockRead data_reads2[] = {
3980 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3981
3982 MockRead("HTTP/1.1 200 OK\r\n"),
3983 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3984 MockRead("Content-Length: 5\r\n\r\n"),
3985 MockRead(SYNCHRONOUS, "hello"),
3986 };
3987
3988 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
3989 data_writes1, arraysize(data_writes1));
3990 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3991 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
3992 data_writes2, arraysize(data_writes2));
3993 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3994 SSLSocketDataProvider ssl(ASYNC, OK);
3995 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3996
danakj1fd259a02016-04-16 03:17:093997 std::unique_ptr<HttpTransaction> trans(
mmenke2a1781d2015-10-07 19:25:333998 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
3999
4000 TestCompletionCallback callback;
4001 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4002 EXPECT_EQ(OK, callback.GetResult(rv));
4003
4004 const HttpResponseInfo* response = trans->GetResponseInfo();
4005 ASSERT_TRUE(response);
4006 ASSERT_TRUE(response->headers);
4007 EXPECT_TRUE(response->headers->IsKeepAlive());
4008 EXPECT_EQ(407, response->headers->response_code());
4009 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4010 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4011 EXPECT_FALSE(response->auth_challenge);
4012
4013 LoadTimingInfo load_timing_info;
4014 // CONNECT requests and responses are handled at the connect job level, so
4015 // the transaction does not yet have a connection.
4016 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4017
4018 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4019 EXPECT_EQ(OK, callback.GetResult(rv));
4020
4021 response = trans->GetResponseInfo();
4022 ASSERT_TRUE(response);
4023 ASSERT_TRUE(response->headers);
4024 EXPECT_TRUE(response->headers->IsKeepAlive());
4025 EXPECT_EQ(200, response->headers->response_code());
4026 EXPECT_EQ(5, response->headers->GetContentLength());
4027 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4028
4029 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524030 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334031
4032 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4033 TestLoadTimingNotReusedWithPac(load_timing_info,
4034 CONNECT_TIMING_HAS_SSL_TIMES);
4035
4036 trans.reset();
4037 session->CloseAllConnections();
4038}
4039
4040// Test a proxy auth scheme that allows default credentials and a proxy server
4041// that hangs up when credentials are initially sent, and hangs up again when
4042// they are retried.
4043TEST_P(HttpNetworkTransactionTest,
4044 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4045 HttpRequestInfo request;
4046 request.method = "GET";
4047 request.url = GURL("https://www.example.org/");
4048
4049 // Configure against proxy server "myproxy:70".
4050 session_deps_.proxy_service =
4051 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4052
danakj1fd259a02016-04-16 03:17:094053 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:334054 new HttpAuthHandlerMock::Factory());
4055 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:094056 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:334057 mock_handler->set_allows_default_credentials(true);
4058 auth_handler_factory->AddMockHandler(mock_handler.release(),
4059 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484060 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334061
4062 // Add NetLog just so can verify load timing information gets a NetLog ID.
4063 NetLog net_log;
4064 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094065 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334066
4067 // Should try to establish tunnel.
4068 MockWrite data_writes1[] = {
4069 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174070 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334071 "Proxy-Connection: keep-alive\r\n\r\n"),
4072
4073 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174074 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334075 "Proxy-Connection: keep-alive\r\n"
4076 "Proxy-Authorization: auth_token\r\n\r\n"),
4077 };
4078
4079 // The proxy responds to the connect with a 407, and then hangs up after the
4080 // second request is sent.
4081 MockRead data_reads1[] = {
4082 // No credentials.
4083 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4084 MockRead("Content-Length: 0\r\n"),
4085 MockRead("Proxy-Connection: keep-alive\r\n"),
4086 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4087 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4088 };
4089
4090 // HttpNetworkTransaction sees a reused connection that was closed with
4091 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4092 // request.
4093 MockWrite data_writes2[] = {
4094 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174095 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334096 "Proxy-Connection: keep-alive\r\n\r\n"),
4097 };
4098
4099 // The proxy, having had more than enough of us, just hangs up.
4100 MockRead data_reads2[] = {
4101 // No credentials.
4102 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4103 };
4104
4105 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4106 data_writes1, arraysize(data_writes1));
4107 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4108 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4109 data_writes2, arraysize(data_writes2));
4110 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4111
danakj1fd259a02016-04-16 03:17:094112 std::unique_ptr<HttpTransaction> trans(
mmenke2a1781d2015-10-07 19:25:334113 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4114
4115 TestCompletionCallback callback;
4116 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4117 EXPECT_EQ(OK, callback.GetResult(rv));
4118
4119 const HttpResponseInfo* response = trans->GetResponseInfo();
4120 ASSERT_TRUE(response);
4121 ASSERT_TRUE(response->headers);
4122 EXPECT_TRUE(response->headers->IsKeepAlive());
4123 EXPECT_EQ(407, response->headers->response_code());
4124 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4125 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4126 EXPECT_FALSE(response->auth_challenge);
4127
4128 LoadTimingInfo load_timing_info;
4129 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4130
4131 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4132 EXPECT_EQ(ERR_EMPTY_RESPONSE, callback.GetResult(rv));
4133
4134 trans.reset();
4135 session->CloseAllConnections();
4136}
4137
4138// Test a proxy auth scheme that allows default credentials and a proxy server
4139// that hangs up when credentials are initially sent, and sends a challenge
4140// again they are retried.
4141TEST_P(HttpNetworkTransactionTest,
4142 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4143 HttpRequestInfo request;
4144 request.method = "GET";
4145 request.url = GURL("https://www.example.org/");
4146
4147 // Configure against proxy server "myproxy:70".
4148 session_deps_.proxy_service =
4149 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
4150
danakj1fd259a02016-04-16 03:17:094151 std::unique_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory(
mmenke2a1781d2015-10-07 19:25:334152 new HttpAuthHandlerMock::Factory());
4153 auth_handler_factory->set_do_init_from_challenge(true);
danakj1fd259a02016-04-16 03:17:094154 std::unique_ptr<HttpAuthHandlerMock> mock_handler(new HttpAuthHandlerMock());
mmenke2a1781d2015-10-07 19:25:334155 mock_handler->set_allows_default_credentials(true);
4156 auth_handler_factory->AddMockHandler(mock_handler.release(),
4157 HttpAuth::AUTH_PROXY);
4158 // Add another handler for the second challenge. It supports default
4159 // credentials, but they shouldn't be used, since they were already tried.
4160 mock_handler.reset(new HttpAuthHandlerMock());
4161 mock_handler->set_allows_default_credentials(true);
4162 auth_handler_factory->AddMockHandler(mock_handler.release(),
4163 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484164 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334165
4166 // Add NetLog just so can verify load timing information gets a NetLog ID.
4167 NetLog net_log;
4168 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094169 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334170
4171 // Should try to establish tunnel.
4172 MockWrite data_writes1[] = {
4173 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174174 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334175 "Proxy-Connection: keep-alive\r\n\r\n"),
4176 };
4177
4178 // The proxy responds to the connect with a 407, using a non-persistent
4179 // connection.
4180 MockRead data_reads1[] = {
4181 // No credentials.
4182 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4183 MockRead("Proxy-Authenticate: Mock\r\n"),
4184 MockRead("Proxy-Connection: close\r\n\r\n"),
4185 };
4186
4187 // Since the first connection was closed, need to establish another once given
4188 // credentials.
4189 MockWrite data_writes2[] = {
4190 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174191 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334192 "Proxy-Connection: keep-alive\r\n"
4193 "Proxy-Authorization: auth_token\r\n\r\n"),
4194 };
4195
4196 MockRead data_reads2[] = {
4197 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4198 MockRead("Proxy-Authenticate: Mock\r\n"),
4199 MockRead("Proxy-Connection: close\r\n\r\n"),
4200 };
4201
4202 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4203 data_writes1, arraysize(data_writes1));
4204 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4205 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
4206 data_writes2, arraysize(data_writes2));
4207 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4208 SSLSocketDataProvider ssl(ASYNC, OK);
4209 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4210
danakj1fd259a02016-04-16 03:17:094211 std::unique_ptr<HttpTransaction> trans(
mmenke2a1781d2015-10-07 19:25:334212 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4213
4214 TestCompletionCallback callback;
4215 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
4216 EXPECT_EQ(OK, callback.GetResult(rv));
4217
4218 const HttpResponseInfo* response = trans->GetResponseInfo();
4219 ASSERT_TRUE(response);
4220 ASSERT_TRUE(response->headers);
4221 EXPECT_EQ(407, response->headers->response_code());
4222 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4223 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4224 EXPECT_FALSE(response->auth_challenge);
4225
4226 LoadTimingInfo load_timing_info;
4227 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4228
4229 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4230 EXPECT_EQ(OK, callback.GetResult(rv));
4231 response = trans->GetResponseInfo();
4232 ASSERT_TRUE(response);
4233 ASSERT_TRUE(response->headers);
4234 EXPECT_EQ(407, response->headers->response_code());
4235 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4236 EXPECT_TRUE(response->auth_challenge);
4237
4238 trans.reset();
4239 session->CloseAllConnections();
4240}
4241
[email protected]029c83b62013-01-24 05:28:204242// Test the load timing for HTTPS requests with an HTTP proxy.
[email protected]23e482282013-06-14 16:08:024243TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204244 HttpRequestInfo request1;
4245 request1.method = "GET";
bncce36dca22015-04-21 22:11:234246 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204247
4248 HttpRequestInfo request2;
4249 request2.method = "GET";
bncce36dca22015-04-21 22:11:234250 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204251
4252 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034253 session_deps_.proxy_service = ProxyService::CreateFixed("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514254 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074255 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094256 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204257
4258 // Since we have proxy, should try to establish tunnel.
4259 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174260 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4261 "Host: www.example.org:443\r\n"
4262 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204263
rsleevidb16bb02015-11-12 23:47:174264 MockWrite("GET /1 HTTP/1.1\r\n"
4265 "Host: www.example.org\r\n"
4266 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204267
rsleevidb16bb02015-11-12 23:47:174268 MockWrite("GET /2 HTTP/1.1\r\n"
4269 "Host: www.example.org\r\n"
4270 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204271 };
4272
4273 // The proxy responds to the connect with a 407, using a persistent
4274 // connection.
4275 MockRead data_reads1[] = {
4276 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4277
4278 MockRead("HTTP/1.1 200 OK\r\n"),
4279 MockRead("Content-Length: 1\r\n\r\n"),
4280 MockRead(SYNCHRONOUS, "1"),
4281
4282 MockRead("HTTP/1.1 200 OK\r\n"),
4283 MockRead("Content-Length: 2\r\n\r\n"),
4284 MockRead(SYNCHRONOUS, "22"),
4285 };
4286
4287 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4288 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074289 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204290 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074291 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204292
4293 TestCompletionCallback callback1;
danakj1fd259a02016-04-16 03:17:094294 std::unique_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:504295 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204296
4297 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
4298 EXPECT_EQ(ERR_IO_PENDING, rv);
4299
4300 rv = callback1.WaitForResult();
4301 EXPECT_EQ(OK, rv);
4302
4303 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524304 ASSERT_TRUE(response1);
4305 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204306 EXPECT_EQ(1, response1->headers->GetContentLength());
4307
4308 LoadTimingInfo load_timing_info1;
4309 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4310 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4311
4312 trans1.reset();
4313
4314 TestCompletionCallback callback2;
danakj1fd259a02016-04-16 03:17:094315 std::unique_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504316 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204317
4318 rv = trans2->Start(&request2, callback2.callback(), log.bound());
4319 EXPECT_EQ(ERR_IO_PENDING, rv);
4320
4321 rv = callback2.WaitForResult();
4322 EXPECT_EQ(OK, rv);
4323
4324 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524325 ASSERT_TRUE(response2);
4326 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204327 EXPECT_EQ(2, response2->headers->GetContentLength());
4328
4329 LoadTimingInfo load_timing_info2;
4330 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4331 TestLoadTimingReused(load_timing_info2);
4332
4333 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4334
4335 trans2.reset();
4336 session->CloseAllConnections();
4337}
4338
4339// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
[email protected]23e482282013-06-14 16:08:024340TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204341 HttpRequestInfo request1;
4342 request1.method = "GET";
bncce36dca22015-04-21 22:11:234343 request1.url = GURL("https://www.example.org/1");
[email protected]029c83b62013-01-24 05:28:204344
4345 HttpRequestInfo request2;
4346 request2.method = "GET";
bncce36dca22015-04-21 22:11:234347 request2.url = GURL("https://www.example.org/2");
[email protected]029c83b62013-01-24 05:28:204348
4349 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034350 session_deps_.proxy_service =
4351 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:514352 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074353 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094354 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204355
4356 // Since we have proxy, should try to establish tunnel.
4357 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174358 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4359 "Host: www.example.org:443\r\n"
4360 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204361
rsleevidb16bb02015-11-12 23:47:174362 MockWrite("GET /1 HTTP/1.1\r\n"
4363 "Host: www.example.org\r\n"
4364 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204365
rsleevidb16bb02015-11-12 23:47:174366 MockWrite("GET /2 HTTP/1.1\r\n"
4367 "Host: www.example.org\r\n"
4368 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204369 };
4370
4371 // The proxy responds to the connect with a 407, using a persistent
4372 // connection.
4373 MockRead data_reads1[] = {
4374 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4375
4376 MockRead("HTTP/1.1 200 OK\r\n"),
4377 MockRead("Content-Length: 1\r\n\r\n"),
4378 MockRead(SYNCHRONOUS, "1"),
4379
4380 MockRead("HTTP/1.1 200 OK\r\n"),
4381 MockRead("Content-Length: 2\r\n\r\n"),
4382 MockRead(SYNCHRONOUS, "22"),
4383 };
4384
4385 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4386 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074387 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204388 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074389 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204390
4391 TestCompletionCallback callback1;
danakj1fd259a02016-04-16 03:17:094392 std::unique_ptr<HttpTransaction> trans1(
[email protected]90499482013-06-01 00:39:504393 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204394
4395 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
4396 EXPECT_EQ(ERR_IO_PENDING, rv);
4397
4398 rv = callback1.WaitForResult();
4399 EXPECT_EQ(OK, rv);
4400
4401 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524402 ASSERT_TRUE(response1);
4403 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204404 EXPECT_EQ(1, response1->headers->GetContentLength());
4405
4406 LoadTimingInfo load_timing_info1;
4407 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4408 TestLoadTimingNotReusedWithPac(load_timing_info1,
4409 CONNECT_TIMING_HAS_SSL_TIMES);
4410
4411 trans1.reset();
4412
4413 TestCompletionCallback callback2;
danakj1fd259a02016-04-16 03:17:094414 std::unique_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:504415 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:204416
4417 rv = trans2->Start(&request2, callback2.callback(), log.bound());
4418 EXPECT_EQ(ERR_IO_PENDING, rv);
4419
4420 rv = callback2.WaitForResult();
4421 EXPECT_EQ(OK, rv);
4422
4423 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524424 ASSERT_TRUE(response2);
4425 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204426 EXPECT_EQ(2, response2->headers->GetContentLength());
4427
4428 LoadTimingInfo load_timing_info2;
4429 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4430 TestLoadTimingReusedWithPac(load_timing_info2);
4431
4432 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4433
4434 trans2.reset();
4435 session->CloseAllConnections();
4436}
4437
[email protected]2df19bb2010-08-25 20:13:464438// Test a simple get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024439TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274440 HttpRequestInfo request;
4441 request.method = "GET";
bncce36dca22015-04-21 22:11:234442 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274443
[email protected]2df19bb2010-08-25 20:13:464444 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034445 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514446 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074447 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094448 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464449
[email protected]2df19bb2010-08-25 20:13:464450 // Since we have proxy, should use full url
4451 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234452 MockWrite(
4453 "GET http://www.example.org/ HTTP/1.1\r\n"
4454 "Host: www.example.org\r\n"
4455 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464456 };
4457
4458 MockRead data_reads1[] = {
4459 MockRead("HTTP/1.1 200 OK\r\n"),
4460 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4461 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064462 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464463 };
4464
4465 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
4466 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:074467 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064468 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074469 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464470
[email protected]49639fa2011-12-20 23:22:414471 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464472
danakj1fd259a02016-04-16 03:17:094473 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504474 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504475
[email protected]49639fa2011-12-20 23:22:414476 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:464477 EXPECT_EQ(ERR_IO_PENDING, rv);
4478
4479 rv = callback1.WaitForResult();
4480 EXPECT_EQ(OK, rv);
4481
[email protected]58e32bb2013-01-21 18:23:254482 LoadTimingInfo load_timing_info;
4483 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4484 TestLoadTimingNotReused(load_timing_info,
4485 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4486
[email protected]2df19bb2010-08-25 20:13:464487 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524488 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:464489
4490 EXPECT_TRUE(response->headers->IsKeepAlive());
4491 EXPECT_EQ(200, response->headers->response_code());
4492 EXPECT_EQ(100, response->headers->GetContentLength());
4493 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4494
4495 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524496 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:464497}
4498
[email protected]7642b5ae2010-09-01 20:55:174499// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024500TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274501 HttpRequestInfo request;
4502 request.method = "GET";
bncce36dca22015-04-21 22:11:234503 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274504 request.load_flags = 0;
4505
[email protected]7642b5ae2010-09-01 20:55:174506 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034507 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514508 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074509 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094510 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:174511
bncce36dca22015-04-21 22:11:234512 // fetch http://www.example.org/ via SPDY
danakj1fd259a02016-04-16 03:17:094513 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:494514 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:134515 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]7642b5ae2010-09-01 20:55:174516
danakj1fd259a02016-04-16 03:17:094517 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:554518 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
danakj1fd259a02016-04-16 03:17:094519 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:554520 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:174521 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134522 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:174523 };
4524
rch8e6c6c42015-05-01 14:05:134525 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4526 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074527 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:174528
[email protected]8ddf8322012-02-23 18:08:064529 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384530 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074531 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:174532
[email protected]49639fa2011-12-20 23:22:414533 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:174534
danakj1fd259a02016-04-16 03:17:094535 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504536 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:504537
[email protected]49639fa2011-12-20 23:22:414538 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]7642b5ae2010-09-01 20:55:174539 EXPECT_EQ(ERR_IO_PENDING, rv);
4540
4541 rv = callback1.WaitForResult();
4542 EXPECT_EQ(OK, rv);
4543
[email protected]58e32bb2013-01-21 18:23:254544 LoadTimingInfo load_timing_info;
4545 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4546 TestLoadTimingNotReused(load_timing_info,
4547 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4548
[email protected]7642b5ae2010-09-01 20:55:174549 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524550 ASSERT_TRUE(response);
4551 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024552 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:174553
4554 std::string response_data;
4555 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:234556 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:174557}
4558
[email protected]1c173852014-06-19 12:51:504559// Verifies that a session which races and wins against the owning transaction
4560// (completing prior to host resolution), doesn't fail the transaction.
4561// Regression test for crbug.com/334413.
4562TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
4563 HttpRequestInfo request;
4564 request.method = "GET";
bncce36dca22015-04-21 22:11:234565 request.url = GURL("http://www.example.org/");
[email protected]1c173852014-06-19 12:51:504566 request.load_flags = 0;
4567
4568 // Configure SPDY proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034569 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514570 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:504571 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094572 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:504573
bncce36dca22015-04-21 22:11:234574 // Fetch http://www.example.org/ through the SPDY proxy.
danakj1fd259a02016-04-16 03:17:094575 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:494576 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rch8e6c6c42015-05-01 14:05:134577 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]1c173852014-06-19 12:51:504578
danakj1fd259a02016-04-16 03:17:094579 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:554580 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:094581 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:554582 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]1c173852014-06-19 12:51:504583 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134584 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:504585 };
4586
rch8e6c6c42015-05-01 14:05:134587 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4588 arraysize(spdy_writes));
[email protected]1c173852014-06-19 12:51:504589 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
4590
4591 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384592 ssl.SetNextProto(GetProtocol());
[email protected]1c173852014-06-19 12:51:504593 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4594
4595 TestCompletionCallback callback1;
4596
danakj1fd259a02016-04-16 03:17:094597 std::unique_ptr<HttpTransaction> trans(
[email protected]1c173852014-06-19 12:51:504598 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
4599
4600 // Stall the hostname resolution begun by the transaction.
4601 session_deps_.host_resolver->set_synchronous_mode(false);
4602 session_deps_.host_resolver->set_ondemand_mode(true);
4603
4604 int rv = trans->Start(&request, callback1.callback(), log.bound());
4605 EXPECT_EQ(ERR_IO_PENDING, rv);
4606
4607 // Race a session to the proxy, which completes first.
4608 session_deps_.host_resolver->set_ondemand_mode(false);
4609 SpdySessionKey key(
4610 HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
4611 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:424612 CreateSecureSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:504613
4614 // Unstall the resolution begun by the transaction.
4615 session_deps_.host_resolver->set_ondemand_mode(true);
4616 session_deps_.host_resolver->ResolveAllPending();
4617
4618 EXPECT_FALSE(callback1.have_result());
4619 rv = callback1.WaitForResult();
4620 EXPECT_EQ(OK, rv);
4621
4622 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524623 ASSERT_TRUE(response);
4624 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024625 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:504626
4627 std::string response_data;
4628 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
4629 EXPECT_EQ(kUploadData, response_data);
4630}
4631
[email protected]dc7bd1c52010-11-12 00:01:134632// Test a SPDY get through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024633TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:274634 HttpRequestInfo request;
4635 request.method = "GET";
bncce36dca22015-04-21 22:11:234636 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274637 request.load_flags = 0;
4638
[email protected]79cb5c12011-09-12 13:12:044639 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:034640 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:514641 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074642 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094643 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:134644
[email protected]dc7bd1c52010-11-12 00:01:134645 // The first request will be a bare GET, the second request will be a
4646 // GET with a Proxy-Authorization header.
danakj1fd259a02016-04-16 03:17:094647 std::unique_ptr<SpdySerializedFrame> req_get(
bnc38dcd392016-02-09 23:19:494648 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
rdsmithebb50aa2015-11-12 03:44:384649 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:134650 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464651 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:134652 };
danakj1fd259a02016-04-16 03:17:094653 std::unique_ptr<SpdySerializedFrame> req_get_authorization(
[email protected]cdf8f7e72013-05-23 10:56:464654 spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
bncb03b1092016-04-06 11:19:554655 arraysize(kExtraAuthorizationHeaders) / 2, 3,
4656 LOWEST, false));
[email protected]dc7bd1c52010-11-12 00:01:134657 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134658 CreateMockWrite(*req_get, 0), CreateMockWrite(*req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:134659 };
4660
4661 // The first response is a 407 proxy authentication challenge, and the second
4662 // response will be a 200 response since the second request includes a valid
4663 // Authorization header.
4664 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:464665 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:134666 };
danakj1fd259a02016-04-16 03:17:094667 std::unique_ptr<SpdySerializedFrame> resp_authentication(
[email protected]23e482282013-06-14 16:08:024668 spdy_util_.ConstructSpdySynReplyError(
bncb03b1092016-04-06 11:19:554669 "407 Proxy Authentication Required", kExtraAuthenticationHeaders,
4670 arraysize(kExtraAuthenticationHeaders) / 2, 1));
danakj1fd259a02016-04-16 03:17:094671 std::unique_ptr<SpdySerializedFrame> body_authentication(
[email protected]23e482282013-06-14 16:08:024672 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:094673 std::unique_ptr<SpdySerializedFrame> resp_data(
[email protected]23e482282013-06-14 16:08:024674 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:094675 std::unique_ptr<SpdySerializedFrame> body_data(
bncb03b1092016-04-06 11:19:554676 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:134677 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134678 CreateMockRead(*resp_authentication, 1),
4679 CreateMockRead(*body_authentication, 2),
4680 CreateMockRead(*resp_data, 4),
4681 CreateMockRead(*body_data, 5),
4682 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:134683 };
4684
rch8e6c6c42015-05-01 14:05:134685 SequencedSocketData data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4686 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074687 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:134688
[email protected]8ddf8322012-02-23 18:08:064689 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384690 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074691 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:134692
[email protected]49639fa2011-12-20 23:22:414693 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:134694
danakj1fd259a02016-04-16 03:17:094695 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504696 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]dc7bd1c52010-11-12 00:01:134697
[email protected]49639fa2011-12-20 23:22:414698 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]dc7bd1c52010-11-12 00:01:134699 EXPECT_EQ(ERR_IO_PENDING, rv);
4700
4701 rv = callback1.WaitForResult();
4702 EXPECT_EQ(OK, rv);
4703
4704 const HttpResponseInfo* const response = trans->GetResponseInfo();
4705
wezca1070932016-05-26 20:30:524706 ASSERT_TRUE(response);
4707 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:134708 EXPECT_EQ(407, response->headers->response_code());
4709 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:434710 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:134711
[email protected]49639fa2011-12-20 23:22:414712 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:134713
[email protected]49639fa2011-12-20 23:22:414714 rv = trans->RestartWithAuth(
4715 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]dc7bd1c52010-11-12 00:01:134716 EXPECT_EQ(ERR_IO_PENDING, rv);
4717
4718 rv = callback2.WaitForResult();
4719 EXPECT_EQ(OK, rv);
4720
4721 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
4722
wezca1070932016-05-26 20:30:524723 ASSERT_TRUE(response_restart);
4724 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:134725 EXPECT_EQ(200, response_restart->headers->response_code());
4726 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524727 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:134728}
4729
[email protected]d9da5fe2010-10-13 22:37:164730// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
[email protected]23e482282013-06-14 16:08:024731TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:274732 HttpRequestInfo request;
4733 request.method = "GET";
bncce36dca22015-04-21 22:11:234734 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274735 request.load_flags = 0;
4736
[email protected]d9da5fe2010-10-13 22:37:164737 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034738 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514739 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074740 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094741 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164742
danakj1fd259a02016-04-16 03:17:094743 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504744 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164745
bncce36dca22015-04-21 22:11:234746 // CONNECT to www.example.org:443 via SPDY
danakj1fd259a02016-04-16 03:17:094747 std::unique_ptr<SpdySerializedFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234748 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4749 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:164750
bncce36dca22015-04-21 22:11:234751 const char get[] =
4752 "GET / HTTP/1.1\r\n"
4753 "Host: www.example.org\r\n"
4754 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:094755 std::unique_ptr<SpdySerializedFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:024756 spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
danakj1fd259a02016-04-16 03:17:094757 std::unique_ptr<SpdySerializedFrame> conn_resp(
[email protected]23e482282013-06-14 16:08:024758 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:164759 const char resp[] = "HTTP/1.1 200 OK\r\n"
4760 "Content-Length: 10\r\n\r\n";
danakj1fd259a02016-04-16 03:17:094761 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024762 spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
danakj1fd259a02016-04-16 03:17:094763 std::unique_ptr<SpdySerializedFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:024764 spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
danakj1fd259a02016-04-16 03:17:094765 std::unique_ptr<SpdySerializedFrame> window_update(
[email protected]c10b20852013-05-15 21:29:204766 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
[email protected]8d2f7012012-02-16 00:08:044767
4768 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134769 CreateMockWrite(*connect, 0),
4770 CreateMockWrite(*wrapped_get, 2),
4771 CreateMockWrite(*window_update, 6),
[email protected]8d2f7012012-02-16 00:08:044772 };
4773
[email protected]d9da5fe2010-10-13 22:37:164774 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134775 CreateMockRead(*conn_resp, 1, ASYNC),
4776 CreateMockRead(*wrapped_get_resp, 3, ASYNC),
4777 CreateMockRead(*wrapped_body, 4, ASYNC),
4778 CreateMockRead(*wrapped_body, 5, ASYNC),
4779 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:164780 };
4781
rch8e6c6c42015-05-01 14:05:134782 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4783 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074784 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164785
[email protected]8ddf8322012-02-23 18:08:064786 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384787 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074788 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064789 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074790 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164791
[email protected]49639fa2011-12-20 23:22:414792 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164793
[email protected]49639fa2011-12-20 23:22:414794 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164795 EXPECT_EQ(ERR_IO_PENDING, rv);
4796
4797 rv = callback1.WaitForResult();
rch8e6c6c42015-05-01 14:05:134798 ASSERT_EQ(OK, rv);
[email protected]d9da5fe2010-10-13 22:37:164799
[email protected]58e32bb2013-01-21 18:23:254800 LoadTimingInfo load_timing_info;
4801 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4802 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4803
[email protected]d9da5fe2010-10-13 22:37:164804 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524805 ASSERT_TRUE(response);
4806 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:164807 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
4808
4809 std::string response_data;
4810 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
4811 EXPECT_EQ("1234567890", response_data);
4812}
4813
4814// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
[email protected]23e482282013-06-14 16:08:024815TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
rdsmithebb50aa2015-11-12 03:44:384816 SpdyTestUtil spdy_util_wrapped(GetProtocol(), GetDependenciesFromPriority());
4817
[email protected]cb9bf6ca2011-01-28 13:15:274818 HttpRequestInfo request;
4819 request.method = "GET";
bncce36dca22015-04-21 22:11:234820 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274821 request.load_flags = 0;
4822
[email protected]d9da5fe2010-10-13 22:37:164823 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034824 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514825 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074826 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094827 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164828
danakj1fd259a02016-04-16 03:17:094829 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504830 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164831
bncce36dca22015-04-21 22:11:234832 // CONNECT to www.example.org:443 via SPDY
danakj1fd259a02016-04-16 03:17:094833 std::unique_ptr<SpdySerializedFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234834 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
4835 // fetch https://www.example.org/ via SPDY
4836 const char kMyUrl[] = "https://www.example.org/";
danakj1fd259a02016-04-16 03:17:094837 std::unique_ptr<SpdySerializedFrame> get(
bnc38dcd392016-02-09 23:19:494838 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
danakj1fd259a02016-04-16 03:17:094839 std::unique_ptr<SpdySerializedFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:024840 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
danakj1fd259a02016-04-16 03:17:094841 std::unique_ptr<SpdySerializedFrame> conn_resp(
[email protected]23e482282013-06-14 16:08:024842 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:094843 std::unique_ptr<SpdySerializedFrame> get_resp(
rdsmithebb50aa2015-11-12 03:44:384844 spdy_util_wrapped.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:094845 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:024846 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
danakj1fd259a02016-04-16 03:17:094847 std::unique_ptr<SpdySerializedFrame> body(
bncb03b1092016-04-06 11:19:554848 spdy_util_wrapped.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:094849 std::unique_ptr<SpdySerializedFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:024850 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
danakj1fd259a02016-04-16 03:17:094851 std::unique_ptr<SpdySerializedFrame> window_update_get_resp(
[email protected]c10b20852013-05-15 21:29:204852 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
danakj1fd259a02016-04-16 03:17:094853 std::unique_ptr<SpdySerializedFrame> window_update_body(
[email protected]c10b20852013-05-15 21:29:204854 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
[email protected]8d2f7012012-02-16 00:08:044855
4856 MockWrite spdy_writes[] = {
rch32320842015-05-16 15:57:094857 CreateMockWrite(*connect, 0),
4858 CreateMockWrite(*wrapped_get, 2),
4859 CreateMockWrite(*window_update_get_resp, 6),
[email protected]8d2f7012012-02-16 00:08:044860 CreateMockWrite(*window_update_body, 7),
4861 };
4862
[email protected]d9da5fe2010-10-13 22:37:164863 MockRead spdy_reads[] = {
rch32320842015-05-16 15:57:094864 CreateMockRead(*conn_resp, 1, ASYNC),
4865 MockRead(ASYNC, ERR_IO_PENDING, 3),
rch8e6c6c42015-05-01 14:05:134866 CreateMockRead(*wrapped_get_resp, 4, ASYNC),
rch32320842015-05-16 15:57:094867 CreateMockRead(*wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:134868 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:164869 };
4870
rch32320842015-05-16 15:57:094871 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4872 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074873 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164874
[email protected]8ddf8322012-02-23 18:08:064875 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384876 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074877 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064878 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384879 ssl2.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074880 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164881
[email protected]49639fa2011-12-20 23:22:414882 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164883
[email protected]49639fa2011-12-20 23:22:414884 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164885 EXPECT_EQ(ERR_IO_PENDING, rv);
4886
rch32320842015-05-16 15:57:094887 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:554888 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:094889 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:594890 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:164891 rv = callback1.WaitForResult();
4892 EXPECT_EQ(OK, rv);
4893
[email protected]58e32bb2013-01-21 18:23:254894 LoadTimingInfo load_timing_info;
4895 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4896 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
4897
[email protected]d9da5fe2010-10-13 22:37:164898 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:524899 ASSERT_TRUE(response);
4900 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:024901 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:164902
4903 std::string response_data;
4904 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
[email protected]448d4ca52012-03-04 04:12:234905 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:164906}
4907
4908// Test a SPDY CONNECT failure through an HTTPS Proxy.
[email protected]23e482282013-06-14 16:08:024909TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:274910 HttpRequestInfo request;
4911 request.method = "GET";
bncce36dca22015-04-21 22:11:234912 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:274913 request.load_flags = 0;
4914
[email protected]d9da5fe2010-10-13 22:37:164915 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034916 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514917 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074918 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094919 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:164920
danakj1fd259a02016-04-16 03:17:094921 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:504922 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]d9da5fe2010-10-13 22:37:164923
bncce36dca22015-04-21 22:11:234924 // CONNECT to www.example.org:443 via SPDY
danakj1fd259a02016-04-16 03:17:094925 std::unique_ptr<SpdySerializedFrame> connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234926 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:094927 std::unique_ptr<SpdySerializedFrame> get(
[email protected]c10b20852013-05-15 21:29:204928 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:164929
4930 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:134931 CreateMockWrite(*connect, 0), CreateMockWrite(*get, 2),
[email protected]d9da5fe2010-10-13 22:37:164932 };
4933
danakj1fd259a02016-04-16 03:17:094934 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:554935 spdy_util_.ConstructSpdySynReplyError(1));
danakj1fd259a02016-04-16 03:17:094936 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:554937 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:164938 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:134939 CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:164940 };
4941
rch8e6c6c42015-05-01 14:05:134942 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
4943 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:074944 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:164945
[email protected]8ddf8322012-02-23 18:08:064946 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384947 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074948 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:064949 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:384950 ssl2.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:074951 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:164952
[email protected]49639fa2011-12-20 23:22:414953 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:164954
[email protected]49639fa2011-12-20 23:22:414955 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]d9da5fe2010-10-13 22:37:164956 EXPECT_EQ(ERR_IO_PENDING, rv);
4957
4958 rv = callback1.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:174959 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]d9da5fe2010-10-13 22:37:164960
ttuttle960fcbf2016-04-19 13:26:324961 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:164962}
4963
[email protected]f6c63db52013-02-02 00:35:224964// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
4965// HTTPS Proxy to different servers.
[email protected]23e482282013-06-14 16:08:024966TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:224967 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
4968 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:034969 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:514970 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074971 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094972 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:504973 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:224974
4975 HttpRequestInfo request1;
4976 request1.method = "GET";
bncce36dca22015-04-21 22:11:234977 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:224978 request1.load_flags = 0;
4979
4980 HttpRequestInfo request2;
4981 request2.method = "GET";
bncce36dca22015-04-21 22:11:234982 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:224983 request2.load_flags = 0;
4984
bncce36dca22015-04-21 22:11:234985 // CONNECT to www.example.org:443 via SPDY.
danakj1fd259a02016-04-16 03:17:094986 std::unique_ptr<SpdySerializedFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:234987 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:094988 std::unique_ptr<SpdySerializedFrame> conn_resp1(
[email protected]23e482282013-06-14 16:08:024989 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:224990
bncce36dca22015-04-21 22:11:234991 // Fetch https://www.example.org/ via HTTP.
4992 const char get1[] =
4993 "GET / HTTP/1.1\r\n"
4994 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:224995 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:094996 std::unique_ptr<SpdySerializedFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:024997 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:224998 const char resp1[] = "HTTP/1.1 200 OK\r\n"
4999 "Content-Length: 1\r\n\r\n";
danakj1fd259a02016-04-16 03:17:095000 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:025001 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
danakj1fd259a02016-04-16 03:17:095002 std::unique_ptr<SpdySerializedFrame> wrapped_body1(
[email protected]23e482282013-06-14 16:08:025003 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
danakj1fd259a02016-04-16 03:17:095004 std::unique_ptr<SpdySerializedFrame> window_update(
[email protected]c10b20852013-05-15 21:29:205005 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:225006
bncce36dca22015-04-21 22:11:235007 // CONNECT to mail.example.org:443 via SPDY.
[email protected]745aa9c2014-06-27 02:21:295008 SpdyHeaderBlock connect2_block;
bnc7ecc1122015-09-28 13:22:495009 spdy_util_.MaybeAddVersionHeader(&connect2_block);
[email protected]745aa9c2014-06-27 02:21:295010 connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
rdsmithebb50aa2015-11-12 03:44:385011 if (GetProtocol() == kProtoHTTP2) {
bnc6b996d532015-07-29 10:51:325012 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org:443";
5013 } else {
bnc6b996d532015-07-29 10:51:325014 connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
bnc7ecc1122015-09-28 13:22:495015 connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
bnc6b996d532015-07-29 10:51:325016 }
danakj1fd259a02016-04-16 03:17:095017 std::unique_ptr<SpdySerializedFrame> connect2(
bnc38dcd392016-02-09 23:19:495018 spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395019
danakj1fd259a02016-04-16 03:17:095020 std::unique_ptr<SpdySerializedFrame> conn_resp2(
[email protected]23e482282013-06-14 16:08:025021 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225022
bncce36dca22015-04-21 22:11:235023 // Fetch https://mail.example.org/ via HTTP.
5024 const char get2[] =
5025 "GET / HTTP/1.1\r\n"
5026 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225027 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:095028 std::unique_ptr<SpdySerializedFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:025029 spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225030 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5031 "Content-Length: 2\r\n\r\n";
danakj1fd259a02016-04-16 03:17:095032 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:025033 spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
danakj1fd259a02016-04-16 03:17:095034 std::unique_ptr<SpdySerializedFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:025035 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225036
5037 MockWrite spdy_writes[] = {
5038 CreateMockWrite(*connect1, 0),
5039 CreateMockWrite(*wrapped_get1, 2),
5040 CreateMockWrite(*connect2, 5),
5041 CreateMockWrite(*wrapped_get2, 7),
5042 };
5043
5044 MockRead spdy_reads[] = {
5045 CreateMockRead(*conn_resp1, 1, ASYNC),
5046 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
5047 CreateMockRead(*wrapped_body1, 4, ASYNC),
5048 CreateMockRead(*conn_resp2, 6, ASYNC),
5049 CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
5050 CreateMockRead(*wrapped_body2, 9, ASYNC),
5051 MockRead(ASYNC, 0, 10),
5052 };
5053
mmenke11eb5152015-06-09 14:50:505054 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5055 arraysize(spdy_writes));
5056 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225057
5058 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:385059 ssl.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:505060 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225061 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505062 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225063 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505064 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225065
5066 TestCompletionCallback callback;
5067
danakj1fd259a02016-04-16 03:17:095068 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505069 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225070 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:505071 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225072
5073 LoadTimingInfo load_timing_info;
5074 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5075 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5076
5077 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525078 ASSERT_TRUE(response);
5079 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225080 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5081
5082 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295083 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505084 rv = trans->Read(buf.get(), 256, callback.callback());
5085 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225086
danakj1fd259a02016-04-16 03:17:095087 std::unique_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:505088 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225089 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:505090 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225091
5092 LoadTimingInfo load_timing_info2;
5093 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5094 // Even though the SPDY connection is reused, a new tunnelled connection has
5095 // to be created, so the socket's load timing looks like a fresh connection.
5096 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5097
5098 // The requests should have different IDs, since they each are using their own
5099 // separate stream.
5100 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5101
mmenke11eb5152015-06-09 14:50:505102 rv = trans2->Read(buf.get(), 256, callback.callback());
5103 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225104}
5105
5106// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5107// HTTPS Proxy to the same server.
[email protected]23e482282013-06-14 16:08:025108TEST_P(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225109 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5110 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035111 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515112 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075113 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095114 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505115 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225116
5117 HttpRequestInfo request1;
5118 request1.method = "GET";
bncce36dca22015-04-21 22:11:235119 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225120 request1.load_flags = 0;
5121
5122 HttpRequestInfo request2;
5123 request2.method = "GET";
bncce36dca22015-04-21 22:11:235124 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225125 request2.load_flags = 0;
5126
bncce36dca22015-04-21 22:11:235127 // CONNECT to www.example.org:443 via SPDY.
danakj1fd259a02016-04-16 03:17:095128 std::unique_ptr<SpdySerializedFrame> connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235129 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:095130 std::unique_ptr<SpdySerializedFrame> conn_resp1(
[email protected]23e482282013-06-14 16:08:025131 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225132
bncce36dca22015-04-21 22:11:235133 // Fetch https://www.example.org/ via HTTP.
5134 const char get1[] =
5135 "GET / HTTP/1.1\r\n"
5136 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225137 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:095138 std::unique_ptr<SpdySerializedFrame> wrapped_get1(
[email protected]23e482282013-06-14 16:08:025139 spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
[email protected]f6c63db52013-02-02 00:35:225140 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5141 "Content-Length: 1\r\n\r\n";
danakj1fd259a02016-04-16 03:17:095142 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp1(
[email protected]23e482282013-06-14 16:08:025143 spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
danakj1fd259a02016-04-16 03:17:095144 std::unique_ptr<SpdySerializedFrame> wrapped_body1(
[email protected]23e482282013-06-14 16:08:025145 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
danakj1fd259a02016-04-16 03:17:095146 std::unique_ptr<SpdySerializedFrame> window_update(
[email protected]c10b20852013-05-15 21:29:205147 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
[email protected]f6c63db52013-02-02 00:35:225148
bncce36dca22015-04-21 22:11:235149 // Fetch https://www.example.org/2 via HTTP.
5150 const char get2[] =
5151 "GET /2 HTTP/1.1\r\n"
5152 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225153 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:095154 std::unique_ptr<SpdySerializedFrame> wrapped_get2(
[email protected]23e482282013-06-14 16:08:025155 spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
[email protected]f6c63db52013-02-02 00:35:225156 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5157 "Content-Length: 2\r\n\r\n";
danakj1fd259a02016-04-16 03:17:095158 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp2(
[email protected]23e482282013-06-14 16:08:025159 spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
danakj1fd259a02016-04-16 03:17:095160 std::unique_ptr<SpdySerializedFrame> wrapped_body2(
[email protected]23e482282013-06-14 16:08:025161 spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
[email protected]f6c63db52013-02-02 00:35:225162
5163 MockWrite spdy_writes[] = {
5164 CreateMockWrite(*connect1, 0),
5165 CreateMockWrite(*wrapped_get1, 2),
5166 CreateMockWrite(*wrapped_get2, 5),
5167 };
5168
5169 MockRead spdy_reads[] = {
5170 CreateMockRead(*conn_resp1, 1, ASYNC),
5171 CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
5172 CreateMockRead(*wrapped_body1, 4, ASYNC),
5173 CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
5174 CreateMockRead(*wrapped_body2, 7, ASYNC),
5175 MockRead(ASYNC, 0, 8),
5176 };
5177
mmenke11eb5152015-06-09 14:50:505178 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5179 arraysize(spdy_writes));
5180 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225181
5182 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:385183 ssl.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:505184 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225185 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505186 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225187
5188 TestCompletionCallback callback;
5189
danakj1fd259a02016-04-16 03:17:095190 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505191 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225192 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
5193 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f6c63db52013-02-02 00:35:225194
5195 rv = callback.WaitForResult();
5196 EXPECT_EQ(OK, rv);
5197
5198 LoadTimingInfo load_timing_info;
5199 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5200 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5201
5202 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525203 ASSERT_TRUE(response);
5204 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225205 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5206
5207 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295208 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
[email protected]90499482013-06-01 00:39:505209 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225210 trans.reset();
5211
danakj1fd259a02016-04-16 03:17:095212 std::unique_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:505213 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225214 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
5215 EXPECT_EQ(ERR_IO_PENDING, rv);
5216
[email protected]f6c63db52013-02-02 00:35:225217 rv = callback.WaitForResult();
5218 EXPECT_EQ(OK, rv);
5219
5220 LoadTimingInfo load_timing_info2;
5221 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5222 TestLoadTimingReused(load_timing_info2);
5223
5224 // The requests should have the same ID.
5225 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5226
[email protected]90499482013-06-01 00:39:505227 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225228}
5229
5230// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5231// Proxy to different servers.
mmenke11eb5152015-06-09 14:50:505232TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225233 // Configure against https proxy server "proxy:70".
rdsmith82957ad2015-09-16 19:42:035234 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:515235 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075236 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095237 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505238 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225239
5240 HttpRequestInfo request1;
5241 request1.method = "GET";
bncce36dca22015-04-21 22:11:235242 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225243 request1.load_flags = 0;
5244
5245 HttpRequestInfo request2;
5246 request2.method = "GET";
bncce36dca22015-04-21 22:11:235247 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225248 request2.load_flags = 0;
5249
bncce36dca22015-04-21 22:11:235250 // http://www.example.org/
danakj1fd259a02016-04-16 03:17:095251 std::unique_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:235252 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
danakj1fd259a02016-04-16 03:17:095253 std::unique_ptr<SpdySerializedFrame> get1(
bnc38dcd392016-02-09 23:19:495254 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true));
danakj1fd259a02016-04-16 03:17:095255 std::unique_ptr<SpdySerializedFrame> get_resp1(
[email protected]23e482282013-06-14 16:08:025256 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:095257 std::unique_ptr<SpdySerializedFrame> body1(
[email protected]23e482282013-06-14 16:08:025258 spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
rdsmithebb50aa2015-11-12 03:44:385259 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225260
bncce36dca22015-04-21 22:11:235261 // http://mail.example.org/
danakj1fd259a02016-04-16 03:17:095262 std::unique_ptr<SpdyHeaderBlock> headers2(
bncce36dca22015-04-21 22:11:235263 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
danakj1fd259a02016-04-16 03:17:095264 std::unique_ptr<SpdySerializedFrame> get2(
bnc38dcd392016-02-09 23:19:495265 spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, true));
danakj1fd259a02016-04-16 03:17:095266 std::unique_ptr<SpdySerializedFrame> get_resp2(
[email protected]23e482282013-06-14 16:08:025267 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:095268 std::unique_ptr<SpdySerializedFrame> body2(
[email protected]23e482282013-06-14 16:08:025269 spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
[email protected]f6c63db52013-02-02 00:35:225270
5271 MockWrite spdy_writes[] = {
5272 CreateMockWrite(*get1, 0),
5273 CreateMockWrite(*get2, 3),
5274 };
5275
5276 MockRead spdy_reads[] = {
5277 CreateMockRead(*get_resp1, 1, ASYNC),
5278 CreateMockRead(*body1, 2, ASYNC),
5279 CreateMockRead(*get_resp2, 4, ASYNC),
5280 CreateMockRead(*body2, 5, ASYNC),
5281 MockRead(ASYNC, 0, 6),
5282 };
5283
mmenke11eb5152015-06-09 14:50:505284 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
5285 arraysize(spdy_writes));
5286 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225287
5288 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:385289 ssl.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:505290 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225291
5292 TestCompletionCallback callback;
5293
danakj1fd259a02016-04-16 03:17:095294 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505295 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225296 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:505297 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225298
5299 LoadTimingInfo load_timing_info;
5300 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5301 TestLoadTimingNotReused(load_timing_info,
5302 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5303
5304 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525305 ASSERT_TRUE(response);
5306 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025307 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225308
5309 std::string response_data;
ttuttle859dc7a2015-04-23 19:42:295310 scoped_refptr<IOBuffer> buf(new IOBuffer(256));
mmenke11eb5152015-06-09 14:50:505311 rv = trans->Read(buf.get(), 256, callback.callback());
5312 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225313 // Delete the first request, so the second one can reuse the socket.
5314 trans.reset();
5315
danakj1fd259a02016-04-16 03:17:095316 std::unique_ptr<HttpTransaction> trans2(
[email protected]90499482013-06-01 00:39:505317 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f6c63db52013-02-02 00:35:225318 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
mmenke11eb5152015-06-09 14:50:505319 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225320
5321 LoadTimingInfo load_timing_info2;
5322 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5323 TestLoadTimingReused(load_timing_info2);
5324
5325 // The requests should have the same ID.
5326 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5327
mmenke11eb5152015-06-09 14:50:505328 rv = trans2->Read(buf.get(), 256, callback.callback());
5329 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225330}
5331
[email protected]2df19bb2010-08-25 20:13:465332// Test the challenge-response-retry sequence through an HTTPS Proxy
[email protected]23e482282013-06-14 16:08:025333TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465334 HttpRequestInfo request;
5335 request.method = "GET";
bncce36dca22015-04-21 22:11:235336 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465337 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295338 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]2df19bb2010-08-25 20:13:465339
[email protected]79cb5c12011-09-12 13:12:045340 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035341 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
vishal.b62985ca92015-04-17 08:45:515342 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075343 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095344 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275345
[email protected]2df19bb2010-08-25 20:13:465346 // Since we have proxy, should use full url
5347 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235348 MockWrite(
5349 "GET http://www.example.org/ HTTP/1.1\r\n"
5350 "Host: www.example.org\r\n"
5351 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465352
bncce36dca22015-04-21 22:11:235353 // After calling trans->RestartWithAuth(), this is the request we should
5354 // be issuing -- the final header line contains the credentials.
5355 MockWrite(
5356 "GET http://www.example.org/ HTTP/1.1\r\n"
5357 "Host: www.example.org\r\n"
5358 "Proxy-Connection: keep-alive\r\n"
5359 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465360 };
5361
5362 // The proxy responds to the GET with a 407, using a persistent
5363 // connection.
5364 MockRead data_reads1[] = {
5365 // No credentials.
5366 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5367 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5368 MockRead("Proxy-Connection: keep-alive\r\n"),
5369 MockRead("Content-Length: 0\r\n\r\n"),
5370
5371 MockRead("HTTP/1.1 200 OK\r\n"),
5372 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5373 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065374 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465375 };
5376
5377 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5378 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:075379 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065380 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075381 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465382
[email protected]49639fa2011-12-20 23:22:415383 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465384
danakj1fd259a02016-04-16 03:17:095385 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505386 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505387
[email protected]49639fa2011-12-20 23:22:415388 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]2df19bb2010-08-25 20:13:465389 EXPECT_EQ(ERR_IO_PENDING, rv);
5390
5391 rv = callback1.WaitForResult();
5392 EXPECT_EQ(OK, rv);
5393
[email protected]58e32bb2013-01-21 18:23:255394 LoadTimingInfo load_timing_info;
5395 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5396 TestLoadTimingNotReused(load_timing_info,
5397 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5398
[email protected]2df19bb2010-08-25 20:13:465399 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525400 ASSERT_TRUE(response);
5401 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465402 EXPECT_EQ(407, response->headers->response_code());
5403 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435404 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465405
[email protected]49639fa2011-12-20 23:22:415406 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465407
[email protected]49639fa2011-12-20 23:22:415408 rv = trans->RestartWithAuth(
5409 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]2df19bb2010-08-25 20:13:465410 EXPECT_EQ(ERR_IO_PENDING, rv);
5411
5412 rv = callback2.WaitForResult();
5413 EXPECT_EQ(OK, rv);
5414
[email protected]58e32bb2013-01-21 18:23:255415 load_timing_info = LoadTimingInfo();
5416 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5417 // Retrying with HTTP AUTH is considered to be reusing a socket.
5418 TestLoadTimingReused(load_timing_info);
5419
[email protected]2df19bb2010-08-25 20:13:465420 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525421 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465422
5423 EXPECT_TRUE(response->headers->IsKeepAlive());
5424 EXPECT_EQ(200, response->headers->response_code());
5425 EXPECT_EQ(100, response->headers->GetContentLength());
5426 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5427
5428 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525429 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465430}
5431
[email protected]23e482282013-06-14 16:08:025432void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085433 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425434 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085435 request.method = "GET";
bncce36dca22015-04-21 22:11:235436 request.url = GURL("https://www.example.org/");
[email protected]c744cf22009-02-27 07:28:085437 request.load_flags = 0;
5438
[email protected]cb9bf6ca2011-01-28 13:15:275439 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035440 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095441 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275442
[email protected]c744cf22009-02-27 07:28:085443 // Since we have proxy, should try to establish tunnel.
5444 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175445 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5446 "Host: www.example.org:443\r\n"
5447 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085448 };
5449
5450 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235451 status, MockRead("Content-Length: 10\r\n\r\n"),
5452 // No response body because the test stops reading here.
5453 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085454 };
5455
[email protected]31a2bfe2010-02-09 08:03:395456 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
5457 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:075458 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085459
[email protected]49639fa2011-12-20 23:22:415460 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085461
danakj1fd259a02016-04-16 03:17:095462 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505463 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505464
[email protected]49639fa2011-12-20 23:22:415465 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425466 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]c744cf22009-02-27 07:28:085467
5468 rv = callback.WaitForResult();
5469 EXPECT_EQ(expected_status, rv);
5470}
5471
[email protected]23e482282013-06-14 16:08:025472void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235473 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085474 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425475 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085476}
5477
[email protected]23e482282013-06-14 16:08:025478TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085479 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5480}
5481
[email protected]23e482282013-06-14 16:08:025482TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085483 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5484}
5485
[email protected]23e482282013-06-14 16:08:025486TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085487 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5488}
5489
[email protected]23e482282013-06-14 16:08:025490TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085491 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5492}
5493
[email protected]23e482282013-06-14 16:08:025494TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085495 ConnectStatusHelper(
5496 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
5497}
5498
[email protected]23e482282013-06-14 16:08:025499TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:085500 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
5501}
5502
[email protected]23e482282013-06-14 16:08:025503TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:085504 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
5505}
5506
[email protected]23e482282013-06-14 16:08:025507TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:085508 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
5509}
5510
[email protected]23e482282013-06-14 16:08:025511TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:085512 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
5513}
5514
[email protected]23e482282013-06-14 16:08:025515TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:085516 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
5517}
5518
[email protected]23e482282013-06-14 16:08:025519TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:085520 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
5521}
5522
[email protected]23e482282013-06-14 16:08:025523TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:085524 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
5525}
5526
[email protected]23e482282013-06-14 16:08:025527TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:085528 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
5529}
5530
[email protected]23e482282013-06-14 16:08:025531TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:085532 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
5533}
5534
[email protected]23e482282013-06-14 16:08:025535TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:085536 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
5537}
5538
[email protected]23e482282013-06-14 16:08:025539TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:085540 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
5541}
5542
[email protected]0a17aab32014-04-24 03:32:375543TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
5544 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
5545}
5546
[email protected]23e482282013-06-14 16:08:025547TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:085548 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
5549}
5550
[email protected]23e482282013-06-14 16:08:025551TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:085552 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
5553}
5554
[email protected]23e482282013-06-14 16:08:025555TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:085556 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
5557}
5558
[email protected]23e482282013-06-14 16:08:025559TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:085560 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
5561}
5562
[email protected]23e482282013-06-14 16:08:025563TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:085564 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
5565}
5566
[email protected]23e482282013-06-14 16:08:025567TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:085568 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
5569}
5570
[email protected]23e482282013-06-14 16:08:025571TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:085572 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
5573}
5574
[email protected]23e482282013-06-14 16:08:025575TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:085576 ConnectStatusHelperWithExpectedStatus(
5577 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:545578 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:085579}
5580
[email protected]23e482282013-06-14 16:08:025581TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:085582 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
5583}
5584
[email protected]23e482282013-06-14 16:08:025585TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:085586 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
5587}
5588
[email protected]23e482282013-06-14 16:08:025589TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:085590 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
5591}
5592
[email protected]23e482282013-06-14 16:08:025593TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:085594 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
5595}
5596
[email protected]23e482282013-06-14 16:08:025597TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:085598 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
5599}
5600
[email protected]23e482282013-06-14 16:08:025601TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:085602 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
5603}
5604
[email protected]23e482282013-06-14 16:08:025605TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:085606 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
5607}
5608
[email protected]23e482282013-06-14 16:08:025609TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:085610 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
5611}
5612
[email protected]23e482282013-06-14 16:08:025613TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:085614 ConnectStatusHelper(
5615 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
5616}
5617
[email protected]23e482282013-06-14 16:08:025618TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:085619 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
5620}
5621
[email protected]23e482282013-06-14 16:08:025622TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:085623 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
5624}
5625
[email protected]23e482282013-06-14 16:08:025626TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:085627 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
5628}
5629
[email protected]23e482282013-06-14 16:08:025630TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:085631 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
5632}
5633
[email protected]23e482282013-06-14 16:08:025634TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:085635 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
5636}
5637
[email protected]23e482282013-06-14 16:08:025638TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:085639 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
5640}
5641
[email protected]23e482282013-06-14 16:08:025642TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:085643 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
5644}
5645
[email protected]038e9a32008-10-08 22:40:165646// Test the flow when both the proxy server AND origin server require
5647// authentication. Again, this uses basic auth for both since that is
5648// the simplest to mock.
[email protected]23e482282013-06-14 16:08:025649TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:275650 HttpRequestInfo request;
5651 request.method = "GET";
bncce36dca22015-04-21 22:11:235652 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:275653 request.load_flags = 0;
5654
[email protected]038e9a32008-10-08 22:40:165655 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:035656 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:095657 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:075658
danakj1fd259a02016-04-16 03:17:095659 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:415660 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]038e9a32008-10-08 22:40:165661
[email protected]f9ee6b52008-11-08 06:46:235662 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235663 MockWrite(
5664 "GET http://www.example.org/ HTTP/1.1\r\n"
5665 "Host: www.example.org\r\n"
5666 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:235667 };
5668
[email protected]038e9a32008-10-08 22:40:165669 MockRead data_reads1[] = {
5670 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
5671 // Give a couple authenticate options (only the middle one is actually
5672 // supported).
[email protected]22927ad2009-09-21 19:56:195673 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:165674 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5675 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
5676 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5677 // Large content-length -- won't matter, as connection will be reset.
5678 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065679 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:165680 };
5681
5682 // After calling trans->RestartWithAuth() the first time, this is the
5683 // request we should be issuing -- the final header line contains the
5684 // proxy's credentials.
5685 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:235686 MockWrite(
5687 "GET http://www.example.org/ HTTP/1.1\r\n"
5688 "Host: www.example.org\r\n"
5689 "Proxy-Connection: keep-alive\r\n"
5690 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165691 };
5692
5693 // Now the proxy server lets the request pass through to origin server.
5694 // The origin server responds with a 401.
5695 MockRead data_reads2[] = {
5696 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
5697 // Note: We are using the same realm-name as the proxy server. This is
5698 // completely valid, as realms are unique across hosts.
5699 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5700 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5701 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065702 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:165703 };
5704
5705 // After calling trans->RestartWithAuth() the second time, we should send
5706 // the credentials for both the proxy and origin server.
5707 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:235708 MockWrite(
5709 "GET http://www.example.org/ HTTP/1.1\r\n"
5710 "Host: www.example.org\r\n"
5711 "Proxy-Connection: keep-alive\r\n"
5712 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
5713 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:165714 };
5715
5716 // Lastly we get the desired content.
5717 MockRead data_reads3[] = {
5718 MockRead("HTTP/1.0 200 OK\r\n"),
5719 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5720 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065721 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:165722 };
5723
[email protected]31a2bfe2010-02-09 08:03:395724 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5725 data_writes1, arraysize(data_writes1));
5726 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5727 data_writes2, arraysize(data_writes2));
5728 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
5729 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:075730 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5731 session_deps_.socket_factory->AddSocketDataProvider(&data2);
5732 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:165733
[email protected]49639fa2011-12-20 23:22:415734 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:165735
[email protected]49639fa2011-12-20 23:22:415736 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425737 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165738
5739 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425740 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165741
[email protected]1c773ea12009-04-28 19:58:425742 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525743 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045744 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165745
[email protected]49639fa2011-12-20 23:22:415746 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:165747
[email protected]49639fa2011-12-20 23:22:415748 rv = trans->RestartWithAuth(
5749 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:425750 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165751
5752 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425753 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165754
5755 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525756 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045757 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:165758
[email protected]49639fa2011-12-20 23:22:415759 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:165760
[email protected]49639fa2011-12-20 23:22:415761 rv = trans->RestartWithAuth(
5762 AuthCredentials(kFoo2, kBar2), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425763 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]038e9a32008-10-08 22:40:165764
5765 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425766 EXPECT_EQ(OK, rv);
[email protected]038e9a32008-10-08 22:40:165767
5768 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525769 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:165770 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:165771}
[email protected]4ddaf2502008-10-23 18:26:195772
[email protected]ea9dc9a2009-09-05 00:43:325773// For the NTLM implementation using SSPI, we skip the NTLM tests since we
5774// can't hook into its internals to cause it to generate predictable NTLM
5775// authorization headers.
5776#if defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:295777// The NTLM authentication unit tests were generated by capturing the HTTP
5778// requests and responses using Fiddler 2 and inspecting the generated random
5779// bytes in the debugger.
5780
5781// Enter the correct password and authenticate successfully.
[email protected]23e482282013-06-14 16:08:025782TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
[email protected]1c773ea12009-04-28 19:58:425783 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:245784 request.method = "GET";
5785 request.url = GURL("http://172.22.68.17/kids/login.aspx");
[email protected]2217aa22013-10-11 03:03:545786
5787 // Ensure load is not disrupted by flags which suppress behaviour specific
5788 // to other auth schemes.
5789 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:245790
[email protected]cb9bf6ca2011-01-28 13:15:275791 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
5792 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095793 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275794
[email protected]3f918782009-02-28 01:29:245795 MockWrite data_writes1[] = {
5796 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5797 "Host: 172.22.68.17\r\n"
5798 "Connection: keep-alive\r\n\r\n"),
5799 };
5800
5801 MockRead data_reads1[] = {
5802 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045803 // Negotiate and NTLM are often requested together. However, we only want
5804 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5805 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:245806 MockRead("WWW-Authenticate: NTLM\r\n"),
5807 MockRead("Connection: close\r\n"),
5808 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365809 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245810 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065811 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]3f918782009-02-28 01:29:245812 };
5813
5814 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:225815 // After restarting with a null identity, this is the
[email protected]3f918782009-02-28 01:29:245816 // request we should be issuing -- the final header line contains a Type
5817 // 1 message.
5818 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5819 "Host: 172.22.68.17\r\n"
5820 "Connection: keep-alive\r\n"
5821 "Authorization: NTLM "
5822 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5823
5824 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5825 // (the credentials for the origin server). The second request continues
5826 // on the same connection.
5827 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5828 "Host: 172.22.68.17\r\n"
5829 "Connection: keep-alive\r\n"
[email protected]385a4672009-03-11 22:21:295830 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5831 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5832 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
5833 "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
5834 "ahlhx5I=\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245835 };
5836
5837 MockRead data_reads2[] = {
5838 // The origin server responds with a Type 2 message.
5839 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5840 MockRead("WWW-Authenticate: NTLM "
[email protected]385a4672009-03-11 22:21:295841 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
[email protected]3f918782009-02-28 01:29:245842 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5843 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5844 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5845 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5846 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5847 "BtAAAAAAA=\r\n"),
5848 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365849 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:245850 MockRead("You are not authorized to view this page\r\n"),
5851
5852 // Lastly we get the desired content.
5853 MockRead("HTTP/1.1 200 OK\r\n"),
5854 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
5855 MockRead("Content-Length: 13\r\n\r\n"),
5856 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:065857 MockRead(SYNCHRONOUS, OK),
[email protected]3f918782009-02-28 01:29:245858 };
5859
[email protected]31a2bfe2010-02-09 08:03:395860 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
5861 data_writes1, arraysize(data_writes1));
5862 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
5863 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:075864 session_deps_.socket_factory->AddSocketDataProvider(&data1);
5865 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:245866
[email protected]49639fa2011-12-20 23:22:415867 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:245868
danakj1fd259a02016-04-16 03:17:095869 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:505870 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:505871
[email protected]49639fa2011-12-20 23:22:415872 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:425873 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:245874
5875 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425876 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:245877
[email protected]0757e7702009-03-27 04:00:225878 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
5879
[email protected]1c773ea12009-04-28 19:58:425880 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525881 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:045882 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:245883
[email protected]49639fa2011-12-20 23:22:415884 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:255885
[email protected]f3cf9802011-10-28 18:44:585886 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:415887 callback2.callback());
[email protected]10af5fe72011-01-31 16:17:255888 EXPECT_EQ(ERR_IO_PENDING, rv);
5889
5890 rv = callback2.WaitForResult();
5891 EXPECT_EQ(OK, rv);
5892
5893 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
5894
5895 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525896 ASSERT_TRUE(response);
5897 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:255898
[email protected]49639fa2011-12-20 23:22:415899 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:245900
[email protected]49639fa2011-12-20 23:22:415901 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:425902 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3f918782009-02-28 01:29:245903
[email protected]0757e7702009-03-27 04:00:225904 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:425905 EXPECT_EQ(OK, rv);
[email protected]3f918782009-02-28 01:29:245906
5907 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525908 ASSERT_TRUE(response);
5909 EXPECT_FALSE(response->auth_challenge);
[email protected]3f918782009-02-28 01:29:245910 EXPECT_EQ(13, response->headers->GetContentLength());
5911}
5912
[email protected]385a4672009-03-11 22:21:295913// Enter a wrong password, and then the correct one.
[email protected]23e482282013-06-14 16:08:025914TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
[email protected]1c773ea12009-04-28 19:58:425915 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:295916 request.method = "GET";
5917 request.url = GURL("http://172.22.68.17/kids/login.aspx");
5918 request.load_flags = 0;
5919
[email protected]cb9bf6ca2011-01-28 13:15:275920 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
5921 MockGetHostName);
danakj1fd259a02016-04-16 03:17:095922 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275923
[email protected]385a4672009-03-11 22:21:295924 MockWrite data_writes1[] = {
5925 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5926 "Host: 172.22.68.17\r\n"
5927 "Connection: keep-alive\r\n\r\n"),
5928 };
5929
5930 MockRead data_reads1[] = {
5931 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:045932 // Negotiate and NTLM are often requested together. However, we only want
5933 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
5934 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:295935 MockRead("WWW-Authenticate: NTLM\r\n"),
5936 MockRead("Connection: close\r\n"),
5937 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365938 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295939 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065940 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:295941 };
5942
5943 MockWrite data_writes2[] = {
[email protected]0757e7702009-03-27 04:00:225944 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:295945 // request we should be issuing -- the final header line contains a Type
5946 // 1 message.
5947 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5948 "Host: 172.22.68.17\r\n"
5949 "Connection: keep-alive\r\n"
5950 "Authorization: NTLM "
5951 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
5952
5953 // After calling trans->RestartWithAuth(), we should send a Type 3 message
5954 // (the credentials for the origin server). The second request continues
5955 // on the same connection.
5956 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5957 "Host: 172.22.68.17\r\n"
5958 "Connection: keep-alive\r\n"
5959 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
5960 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
5961 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
5962 "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
5963 "4Ww7b7E=\r\n\r\n"),
5964 };
5965
5966 MockRead data_reads2[] = {
5967 // The origin server responds with a Type 2 message.
5968 MockRead("HTTP/1.1 401 Access Denied\r\n"),
5969 MockRead("WWW-Authenticate: NTLM "
5970 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
5971 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
5972 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
5973 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
5974 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
5975 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
5976 "BtAAAAAAA=\r\n"),
5977 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365978 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295979 MockRead("You are not authorized to view this page\r\n"),
5980
5981 // Wrong password.
5982 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]385a4672009-03-11 22:21:295983 MockRead("WWW-Authenticate: NTLM\r\n"),
5984 MockRead("Connection: close\r\n"),
5985 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:365986 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:295987 // Missing content -- won't matter, as connection will be reset.
[email protected]8ddf8322012-02-23 18:08:065988 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]385a4672009-03-11 22:21:295989 };
5990
5991 MockWrite data_writes3[] = {
[email protected]0757e7702009-03-27 04:00:225992 // After restarting with a null identity, this is the
[email protected]385a4672009-03-11 22:21:295993 // request we should be issuing -- the final header line contains a Type
5994 // 1 message.
5995 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
5996 "Host: 172.22.68.17\r\n"
5997 "Connection: keep-alive\r\n"
5998 "Authorization: NTLM "
5999 "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
6000
6001 // After calling trans->RestartWithAuth(), we should send a Type 3 message
6002 // (the credentials for the origin server). The second request continues
6003 // on the same connection.
6004 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6005 "Host: 172.22.68.17\r\n"
6006 "Connection: keep-alive\r\n"
6007 "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
6008 "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
6009 "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
6010 "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
6011 "+4MUm7c=\r\n\r\n"),
6012 };
6013
6014 MockRead data_reads3[] = {
6015 // The origin server responds with a Type 2 message.
6016 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6017 MockRead("WWW-Authenticate: NTLM "
6018 "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
6019 "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
6020 "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
6021 "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
6022 "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
6023 "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
6024 "BtAAAAAAA=\r\n"),
6025 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366026 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296027 MockRead("You are not authorized to view this page\r\n"),
6028
6029 // Lastly we get the desired content.
6030 MockRead("HTTP/1.1 200 OK\r\n"),
6031 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6032 MockRead("Content-Length: 13\r\n\r\n"),
6033 MockRead("Please Login\r\n"),
[email protected]8ddf8322012-02-23 18:08:066034 MockRead(SYNCHRONOUS, OK),
[email protected]385a4672009-03-11 22:21:296035 };
6036
[email protected]31a2bfe2010-02-09 08:03:396037 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6038 data_writes1, arraysize(data_writes1));
6039 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6040 data_writes2, arraysize(data_writes2));
6041 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6042 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076043 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6044 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6045 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296046
[email protected]49639fa2011-12-20 23:22:416047 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296048
danakj1fd259a02016-04-16 03:17:096049 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506050 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:506051
[email protected]49639fa2011-12-20 23:22:416052 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426053 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:296054
6055 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426056 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:296057
[email protected]0757e7702009-03-27 04:00:226058 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296059
[email protected]1c773ea12009-04-28 19:58:426060 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526061 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046062 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296063
[email protected]49639fa2011-12-20 23:22:416064 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296065
[email protected]0757e7702009-03-27 04:00:226066 // Enter the wrong password.
[email protected]f3cf9802011-10-28 18:44:586067 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
[email protected]49639fa2011-12-20 23:22:416068 callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426069 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]385a4672009-03-11 22:21:296070
[email protected]10af5fe72011-01-31 16:17:256071 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426072 EXPECT_EQ(OK, rv);
[email protected]385a4672009-03-11 22:21:296073
[email protected]0757e7702009-03-27 04:00:226074 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416075 TestCompletionCallback callback3;
6076 rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:426077 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]10af5fe72011-01-31 16:17:256078 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426079 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226080 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6081
6082 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526083 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046084 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226085
[email protected]49639fa2011-12-20 23:22:416086 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226087
6088 // Now enter the right password.
[email protected]f3cf9802011-10-28 18:44:586089 rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
[email protected]49639fa2011-12-20 23:22:416090 callback4.callback());
[email protected]10af5fe72011-01-31 16:17:256091 EXPECT_EQ(ERR_IO_PENDING, rv);
6092
6093 rv = callback4.WaitForResult();
6094 EXPECT_EQ(OK, rv);
6095
6096 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
6097
[email protected]49639fa2011-12-20 23:22:416098 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256099
6100 // One more roundtrip
[email protected]49639fa2011-12-20 23:22:416101 rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
[email protected]1c773ea12009-04-28 19:58:426102 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:226103
6104 rv = callback5.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426105 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226106
[email protected]385a4672009-03-11 22:21:296107 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526108 EXPECT_FALSE(response->auth_challenge);
[email protected]385a4672009-03-11 22:21:296109 EXPECT_EQ(13, response->headers->GetContentLength());
6110}
[email protected]ea9dc9a2009-09-05 00:43:326111#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296112
[email protected]4ddaf2502008-10-23 18:26:196113// Test reading a server response which has only headers, and no body.
6114// After some maximum number of bytes is consumed, the transaction should
6115// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
[email protected]23e482282013-06-14 16:08:026116TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426117 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196118 request.method = "GET";
bncce36dca22015-04-21 22:11:236119 request.url = GURL("http://www.example.org/");
[email protected]4ddaf2502008-10-23 18:26:196120 request.load_flags = 0;
6121
danakj1fd259a02016-04-16 03:17:096122 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6123 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416124 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276125
[email protected]b75b7b2f2009-10-06 00:54:536126 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:436127 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:536128 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:196129
6130 MockRead data_reads[] = {
6131 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:066132 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:196133 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:066134 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:196135 };
[email protected]31a2bfe2010-02-09 08:03:396136 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076137 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:196138
[email protected]49639fa2011-12-20 23:22:416139 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:196140
[email protected]49639fa2011-12-20 23:22:416141 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426142 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]4ddaf2502008-10-23 18:26:196143
6144 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426145 EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
[email protected]4ddaf2502008-10-23 18:26:196146}
[email protected]f4e426b2008-11-05 00:24:496147
6148// Make sure that we don't try to reuse a TCPClientSocket when failing to
6149// establish tunnel.
6150// http://code.google.com/p/chromium/issues/detail?id=3772
[email protected]23e482282013-06-14 16:08:026151TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:236152 DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:276153 HttpRequestInfo request;
6154 request.method = "GET";
bncce36dca22015-04-21 22:11:236155 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:276156 request.load_flags = 0;
6157
[email protected]f4e426b2008-11-05 00:24:496158 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:036159 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]db8f44c2008-12-13 04:52:016160
danakj1fd259a02016-04-16 03:17:096161 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:496162
danakj1fd259a02016-04-16 03:17:096163 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506164 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]f4e426b2008-11-05 00:24:496165
[email protected]f4e426b2008-11-05 00:24:496166 // Since we have proxy, should try to establish tunnel.
6167 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:176168 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6169 "Host: www.example.org:443\r\n"
6170 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:496171 };
6172
[email protected]77848d12008-11-14 00:00:226173 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:496174 // connection. Usually a proxy would return 501 (not implemented),
6175 // or 200 (tunnel established).
6176 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:236177 MockRead("HTTP/1.1 404 Not Found\r\n"),
6178 MockRead("Content-Length: 10\r\n\r\n"),
6179 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:496180 };
6181
[email protected]31a2bfe2010-02-09 08:03:396182 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6183 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:076184 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:496185
[email protected]49639fa2011-12-20 23:22:416186 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:496187
[email protected]49639fa2011-12-20 23:22:416188 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426189 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f4e426b2008-11-05 00:24:496190
6191 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426192 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]f4e426b2008-11-05 00:24:496193
[email protected]b4404c02009-04-10 16:38:526194 // Empty the current queue. This is necessary because idle sockets are
6195 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556196 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526197
[email protected]f4e426b2008-11-05 00:24:496198 // We now check to make sure the TCPClientSocket was not added back to
6199 // the pool.
[email protected]90499482013-06-01 00:39:506200 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496201 trans.reset();
fdoray92e35a72016-06-10 15:54:556202 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:496203 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:506204 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:496205}
[email protected]372d34a2008-11-05 21:30:516206
[email protected]1b157c02009-04-21 01:55:406207// Make sure that we recycle a socket after reading all of the response body.
[email protected]23e482282013-06-14 16:08:026208TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:426209 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:406210 request.method = "GET";
bncce36dca22015-04-21 22:11:236211 request.url = GURL("http://www.example.org/");
[email protected]1b157c02009-04-21 01:55:406212 request.load_flags = 0;
6213
danakj1fd259a02016-04-16 03:17:096214 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276215
danakj1fd259a02016-04-16 03:17:096216 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506217 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276218
[email protected]1b157c02009-04-21 01:55:406219 MockRead data_reads[] = {
6220 // A part of the response body is received with the response headers.
6221 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
6222 // The rest of the response body is received in two parts.
6223 MockRead("lo"),
6224 MockRead(" world"),
6225 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066226 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:406227 };
6228
[email protected]31a2bfe2010-02-09 08:03:396229 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076230 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:406231
[email protected]49639fa2011-12-20 23:22:416232 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:406233
[email protected]49639fa2011-12-20 23:22:416234 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426235 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]1b157c02009-04-21 01:55:406236
6237 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426238 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:406239
[email protected]1c773ea12009-04-28 19:58:426240 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526241 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:406242
wezca1070932016-05-26 20:30:526243 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:406244 std::string status_line = response->headers->GetStatusLine();
6245 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
6246
[email protected]90499482013-06-01 00:39:506247 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406248
6249 std::string response_data;
6250 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:426251 EXPECT_EQ(OK, rv);
[email protected]1b157c02009-04-21 01:55:406252 EXPECT_EQ("hello world", response_data);
6253
6254 // Empty the current queue. This is necessary because idle sockets are
6255 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556256 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:406257
6258 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506259 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:406260}
6261
[email protected]76a505b2010-08-25 06:23:006262// Make sure that we recycle a SSL socket after reading all of the response
6263// body.
[email protected]23e482282013-06-14 16:08:026264TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006265 HttpRequestInfo request;
6266 request.method = "GET";
bncce36dca22015-04-21 22:11:236267 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006268 request.load_flags = 0;
6269
6270 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236271 MockWrite(
6272 "GET / HTTP/1.1\r\n"
6273 "Host: www.example.org\r\n"
6274 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006275 };
6276
6277 MockRead data_reads[] = {
6278 MockRead("HTTP/1.1 200 OK\r\n"),
6279 MockRead("Content-Length: 11\r\n\r\n"),
6280 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066281 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:006282 };
6283
[email protected]8ddf8322012-02-23 18:08:066284 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076285 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:006286
6287 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6288 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076289 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:006290
[email protected]49639fa2011-12-20 23:22:416291 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006292
danakj1fd259a02016-04-16 03:17:096293 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6294 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506295 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006296
[email protected]49639fa2011-12-20 23:22:416297 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:006298
6299 EXPECT_EQ(ERR_IO_PENDING, rv);
6300 EXPECT_EQ(OK, callback.WaitForResult());
6301
6302 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526303 ASSERT_TRUE(response);
6304 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006305 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6306
[email protected]90499482013-06-01 00:39:506307 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006308
6309 std::string response_data;
6310 rv = ReadTransaction(trans.get(), &response_data);
6311 EXPECT_EQ(OK, rv);
6312 EXPECT_EQ("hello world", response_data);
6313
6314 // Empty the current queue. This is necessary because idle sockets are
6315 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556316 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006317
6318 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506319 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006320}
6321
6322// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
6323// from the pool and make sure that we recover okay.
[email protected]23e482282013-06-14 16:08:026324TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:006325 HttpRequestInfo request;
6326 request.method = "GET";
bncce36dca22015-04-21 22:11:236327 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:006328 request.load_flags = 0;
6329
6330 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:236331 MockWrite(
6332 "GET / HTTP/1.1\r\n"
6333 "Host: www.example.org\r\n"
6334 "Connection: keep-alive\r\n\r\n"),
6335 MockWrite(
6336 "GET / HTTP/1.1\r\n"
6337 "Host: www.example.org\r\n"
6338 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:006339 };
6340
6341 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:426342 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
6343 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:006344
[email protected]8ddf8322012-02-23 18:08:066345 SSLSocketDataProvider ssl(ASYNC, OK);
6346 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076347 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6348 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:006349
6350 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
6351 data_writes, arraysize(data_writes));
6352 StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
6353 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:076354 session_deps_.socket_factory->AddSocketDataProvider(&data);
6355 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:006356
[email protected]49639fa2011-12-20 23:22:416357 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:006358
danakj1fd259a02016-04-16 03:17:096359 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6360 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506361 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006362
[email protected]49639fa2011-12-20 23:22:416363 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:006364
6365 EXPECT_EQ(ERR_IO_PENDING, rv);
6366 EXPECT_EQ(OK, callback.WaitForResult());
6367
6368 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526369 ASSERT_TRUE(response);
6370 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006371 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6372
[email protected]90499482013-06-01 00:39:506373 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006374
6375 std::string response_data;
6376 rv = ReadTransaction(trans.get(), &response_data);
6377 EXPECT_EQ(OK, rv);
6378 EXPECT_EQ("hello world", response_data);
6379
6380 // Empty the current queue. This is necessary because idle sockets are
6381 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556382 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006383
6384 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506385 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006386
6387 // Now start the second transaction, which should reuse the previous socket.
6388
[email protected]90499482013-06-01 00:39:506389 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]76a505b2010-08-25 06:23:006390
[email protected]49639fa2011-12-20 23:22:416391 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]76a505b2010-08-25 06:23:006392
6393 EXPECT_EQ(ERR_IO_PENDING, rv);
6394 EXPECT_EQ(OK, callback.WaitForResult());
6395
6396 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526397 ASSERT_TRUE(response);
6398 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:006399 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6400
[email protected]90499482013-06-01 00:39:506401 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006402
6403 rv = ReadTransaction(trans.get(), &response_data);
6404 EXPECT_EQ(OK, rv);
6405 EXPECT_EQ("hello world", response_data);
6406
6407 // Empty the current queue. This is necessary because idle sockets are
6408 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556409 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:006410
6411 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506412 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:006413}
6414
[email protected]b4404c02009-04-10 16:38:526415// Make sure that we recycle a socket after a zero-length response.
6416// http://crbug.com/9880
[email protected]23e482282013-06-14 16:08:026417TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:426418 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:526419 request.method = "GET";
bncce36dca22015-04-21 22:11:236420 request.url = GURL(
6421 "http://www.example.org/csi?v=3&s=web&action=&"
6422 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
6423 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
6424 "rt=prt.2642,ol.2649,xjs.2951");
[email protected]b4404c02009-04-10 16:38:526425 request.load_flags = 0;
6426
danakj1fd259a02016-04-16 03:17:096427 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276428
[email protected]b4404c02009-04-10 16:38:526429 MockRead data_reads[] = {
6430 MockRead("HTTP/1.1 204 No Content\r\n"
6431 "Content-Length: 0\r\n"
6432 "Content-Type: text/html\r\n\r\n"),
6433 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:066434 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:526435 };
6436
[email protected]31a2bfe2010-02-09 08:03:396437 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:076438 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:526439
mmenkecc2298e2015-12-07 18:20:186440 // Transaction must be created after the MockReads, so it's destroyed before
6441 // them.
danakj1fd259a02016-04-16 03:17:096442 std::unique_ptr<HttpTransaction> trans(
mmenkecc2298e2015-12-07 18:20:186443 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
6444
[email protected]49639fa2011-12-20 23:22:416445 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:526446
[email protected]49639fa2011-12-20 23:22:416447 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426448 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]b4404c02009-04-10 16:38:526449
6450 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426451 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:526452
[email protected]1c773ea12009-04-28 19:58:426453 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526454 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:526455
wezca1070932016-05-26 20:30:526456 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:526457 std::string status_line = response->headers->GetStatusLine();
6458 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
6459
[email protected]90499482013-06-01 00:39:506460 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526461
6462 std::string response_data;
6463 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:426464 EXPECT_EQ(OK, rv);
[email protected]b4404c02009-04-10 16:38:526465 EXPECT_EQ("", response_data);
6466
6467 // Empty the current queue. This is necessary because idle sockets are
6468 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:556469 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:526470
6471 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:506472 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:526473}
6474
[email protected]23e482282013-06-14 16:08:026475TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:096476 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:226477 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:096478 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:226479 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:276480
[email protected]1c773ea12009-04-28 19:58:426481 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:516482 // Transaction 1: a GET request that succeeds. The socket is recycled
6483 // after use.
6484 request[0].method = "GET";
6485 request[0].url = GURL("http://www.google.com/");
6486 request[0].load_flags = 0;
6487 // Transaction 2: a POST request. Reuses the socket kept alive from
6488 // transaction 1. The first attempts fails when writing the POST data.
6489 // This causes the transaction to retry with a new socket. The second
6490 // attempt succeeds.
6491 request[1].method = "POST";
6492 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:276493 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:516494 request[1].load_flags = 0;
6495
danakj1fd259a02016-04-16 03:17:096496 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:516497
6498 // The first socket is used for transaction 1 and the first attempt of
6499 // transaction 2.
6500
6501 // The response of transaction 1.
6502 MockRead data_reads1[] = {
6503 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
6504 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:066505 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516506 };
6507 // The mock write results of transaction 1 and the first attempt of
6508 // transaction 2.
6509 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:066510 MockWrite(SYNCHRONOUS, 64), // GET
6511 MockWrite(SYNCHRONOUS, 93), // POST
6512 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:516513 };
[email protected]31a2bfe2010-02-09 08:03:396514 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6515 data_writes1, arraysize(data_writes1));
[email protected]372d34a2008-11-05 21:30:516516
6517 // The second socket is used for the second attempt of transaction 2.
6518
6519 // The response of transaction 2.
6520 MockRead data_reads2[] = {
6521 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
6522 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:066523 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:516524 };
6525 // The mock write results of the second attempt of transaction 2.
6526 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:066527 MockWrite(SYNCHRONOUS, 93), // POST
6528 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:516529 };
[email protected]31a2bfe2010-02-09 08:03:396530 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6531 data_writes2, arraysize(data_writes2));
[email protected]372d34a2008-11-05 21:30:516532
[email protected]bb88e1d32013-05-03 23:11:076533 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6534 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:516535
thestig9d3bb0c2015-01-24 00:49:516536 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:516537 "hello world", "welcome"
6538 };
6539
6540 for (int i = 0; i < 2; ++i) {
danakj1fd259a02016-04-16 03:17:096541 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506542 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]372d34a2008-11-05 21:30:516543
[email protected]49639fa2011-12-20 23:22:416544 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:516545
[email protected]49639fa2011-12-20 23:22:416546 int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426547 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]372d34a2008-11-05 21:30:516548
6549 rv = callback.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426550 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:516551
[email protected]1c773ea12009-04-28 19:58:426552 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526553 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:516554
wezca1070932016-05-26 20:30:526555 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:516556 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6557
6558 std::string response_data;
6559 rv = ReadTransaction(trans.get(), &response_data);
[email protected]1c773ea12009-04-28 19:58:426560 EXPECT_EQ(OK, rv);
[email protected]372d34a2008-11-05 21:30:516561 EXPECT_EQ(kExpectedResponseData[i], response_data);
6562 }
6563}
[email protected]f9ee6b52008-11-08 06:46:236564
6565// Test the request-challenge-retry sequence for basic auth when there is
6566// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:166567// it fails the identity from the URL is used to answer the challenge.
[email protected]23e482282013-06-14 16:08:026568TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:426569 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236570 request.method = "GET";
bncce36dca22015-04-21 22:11:236571 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:416572 request.load_flags = LOAD_NORMAL;
[email protected]a97cca42009-08-14 01:00:296573
danakj1fd259a02016-04-16 03:17:096574 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6575 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416576 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276577
[email protected]a97cca42009-08-14 01:00:296578 // The password contains an escaped character -- for this test to pass it
6579 // will need to be unescaped by HttpNetworkTransaction.
6580 EXPECT_EQ("b%40r", request.url.password());
6581
[email protected]f9ee6b52008-11-08 06:46:236582 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236583 MockWrite(
6584 "GET / HTTP/1.1\r\n"
6585 "Host: www.example.org\r\n"
6586 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236587 };
6588
6589 MockRead data_reads1[] = {
6590 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6591 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6592 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066593 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236594 };
6595
[email protected]2262e3a2012-05-22 16:08:166596 // After the challenge above, the transaction will be restarted using the
6597 // identity from the url (foo, b@r) to answer the challenge.
6598 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236599 MockWrite(
6600 "GET / HTTP/1.1\r\n"
6601 "Host: www.example.org\r\n"
6602 "Connection: keep-alive\r\n"
6603 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166604 };
6605
6606 MockRead data_reads2[] = {
6607 MockRead("HTTP/1.0 200 OK\r\n"),
6608 MockRead("Content-Length: 100\r\n\r\n"),
6609 MockRead(SYNCHRONOUS, OK),
6610 };
6611
[email protected]31a2bfe2010-02-09 08:03:396612 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6613 data_writes1, arraysize(data_writes1));
[email protected]2262e3a2012-05-22 16:08:166614 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6615 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076616 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6617 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236618
[email protected]49639fa2011-12-20 23:22:416619 TestCompletionCallback callback1;
[email protected]49639fa2011-12-20 23:22:416620 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426621 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236622 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426623 EXPECT_EQ(OK, rv);
[email protected]2262e3a2012-05-22 16:08:166624 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
6625
6626 TestCompletionCallback callback2;
6627 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
6628 EXPECT_EQ(ERR_IO_PENDING, rv);
6629 rv = callback2.WaitForResult();
6630 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:226631 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6632
[email protected]2262e3a2012-05-22 16:08:166633 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526634 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166635
6636 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:526637 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166638
6639 EXPECT_EQ(100, response->headers->GetContentLength());
6640
6641 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556642 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:166643}
6644
6645// Test the request-challenge-retry sequence for basic auth when there is an
6646// incorrect identity in the URL. The identity from the URL should be used only
6647// once.
[email protected]23e482282013-06-14 16:08:026648TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:166649 HttpRequestInfo request;
6650 request.method = "GET";
6651 // Note: the URL has a username:password in it. The password "baz" is
6652 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:236653 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:166654
6655 request.load_flags = LOAD_NORMAL;
6656
danakj1fd259a02016-04-16 03:17:096657 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6658 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416659 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2262e3a2012-05-22 16:08:166660
6661 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236662 MockWrite(
6663 "GET / HTTP/1.1\r\n"
6664 "Host: www.example.org\r\n"
6665 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166666 };
6667
6668 MockRead data_reads1[] = {
6669 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6670 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6671 MockRead("Content-Length: 10\r\n\r\n"),
6672 MockRead(SYNCHRONOUS, ERR_FAILED),
6673 };
6674
6675 // After the challenge above, the transaction will be restarted using the
6676 // identity from the url (foo, baz) to answer the challenge.
6677 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236678 MockWrite(
6679 "GET / HTTP/1.1\r\n"
6680 "Host: www.example.org\r\n"
6681 "Connection: keep-alive\r\n"
6682 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166683 };
6684
6685 MockRead data_reads2[] = {
6686 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6687 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6688 MockRead("Content-Length: 10\r\n\r\n"),
6689 MockRead(SYNCHRONOUS, ERR_FAILED),
6690 };
6691
6692 // After the challenge above, the transaction will be restarted using the
6693 // identity supplied by the user (foo, bar) to answer the challenge.
6694 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236695 MockWrite(
6696 "GET / HTTP/1.1\r\n"
6697 "Host: www.example.org\r\n"
6698 "Connection: keep-alive\r\n"
6699 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:166700 };
6701
6702 MockRead data_reads3[] = {
6703 MockRead("HTTP/1.0 200 OK\r\n"),
6704 MockRead("Content-Length: 100\r\n\r\n"),
6705 MockRead(SYNCHRONOUS, OK),
6706 };
6707
6708 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6709 data_writes1, arraysize(data_writes1));
6710 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6711 data_writes2, arraysize(data_writes2));
6712 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6713 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:076714 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6715 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6716 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:166717
6718 TestCompletionCallback callback1;
6719
6720 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
6721 EXPECT_EQ(ERR_IO_PENDING, rv);
6722
6723 rv = callback1.WaitForResult();
6724 EXPECT_EQ(OK, rv);
6725
6726 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
6727 TestCompletionCallback callback2;
6728 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
6729 EXPECT_EQ(ERR_IO_PENDING, rv);
6730 rv = callback2.WaitForResult();
6731 EXPECT_EQ(OK, rv);
6732 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6733
6734 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526735 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166736 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6737
6738 TestCompletionCallback callback3;
6739 rv = trans->RestartWithAuth(
6740 AuthCredentials(kFoo, kBar), callback3.callback());
6741 EXPECT_EQ(ERR_IO_PENDING, rv);
6742 rv = callback3.WaitForResult();
6743 EXPECT_EQ(OK, rv);
6744 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6745
6746 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526747 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:166748
6749 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:526750 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:166751
6752 EXPECT_EQ(100, response->headers->GetContentLength());
6753
[email protected]ea9dc9a2009-09-05 00:43:326754 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556755 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:326756}
6757
[email protected]2217aa22013-10-11 03:03:546758
6759// Test the request-challenge-retry sequence for basic auth when there is a
6760// correct identity in the URL, but its use is being suppressed. The identity
6761// from the URL should never be used.
6762TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
6763 HttpRequestInfo request;
6764 request.method = "GET";
bncce36dca22015-04-21 22:11:236765 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:546766 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6767
danakj1fd259a02016-04-16 03:17:096768 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6769 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:416770 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2217aa22013-10-11 03:03:546771
6772 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236773 MockWrite(
6774 "GET / HTTP/1.1\r\n"
6775 "Host: www.example.org\r\n"
6776 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546777 };
6778
6779 MockRead data_reads1[] = {
6780 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6781 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6782 MockRead("Content-Length: 10\r\n\r\n"),
6783 MockRead(SYNCHRONOUS, ERR_FAILED),
6784 };
6785
6786 // After the challenge above, the transaction will be restarted using the
6787 // identity supplied by the user, not the one in the URL, to answer the
6788 // challenge.
6789 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236790 MockWrite(
6791 "GET / HTTP/1.1\r\n"
6792 "Host: www.example.org\r\n"
6793 "Connection: keep-alive\r\n"
6794 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:546795 };
6796
6797 MockRead data_reads3[] = {
6798 MockRead("HTTP/1.0 200 OK\r\n"),
6799 MockRead("Content-Length: 100\r\n\r\n"),
6800 MockRead(SYNCHRONOUS, OK),
6801 };
6802
6803 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6804 data_writes1, arraysize(data_writes1));
6805 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
6806 data_writes3, arraysize(data_writes3));
6807 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6808 session_deps_.socket_factory->AddSocketDataProvider(&data3);
6809
6810 TestCompletionCallback callback1;
6811 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
6812 EXPECT_EQ(ERR_IO_PENDING, rv);
6813 rv = callback1.WaitForResult();
6814 EXPECT_EQ(OK, rv);
6815 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6816
6817 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526818 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:546819 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
6820
6821 TestCompletionCallback callback3;
6822 rv = trans->RestartWithAuth(
6823 AuthCredentials(kFoo, kBar), callback3.callback());
6824 EXPECT_EQ(ERR_IO_PENDING, rv);
6825 rv = callback3.WaitForResult();
6826 EXPECT_EQ(OK, rv);
6827 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
6828
6829 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526830 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:546831
6832 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:526833 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:546834 EXPECT_EQ(100, response->headers->GetContentLength());
6835
6836 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:556837 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:546838}
6839
[email protected]f9ee6b52008-11-08 06:46:236840// Test that previously tried username/passwords for a realm get re-used.
[email protected]23e482282013-06-14 16:08:026841TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:096842 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:236843
6844 // Transaction 1: authenticate (foo, bar) on MyRealm1
6845 {
[email protected]1c773ea12009-04-28 19:58:426846 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236847 request.method = "GET";
bncce36dca22015-04-21 22:11:236848 request.url = GURL("http://www.example.org/x/y/z");
[email protected]f9ee6b52008-11-08 06:46:236849 request.load_flags = 0;
6850
danakj1fd259a02016-04-16 03:17:096851 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506852 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276853
[email protected]f9ee6b52008-11-08 06:46:236854 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236855 MockWrite(
6856 "GET /x/y/z HTTP/1.1\r\n"
6857 "Host: www.example.org\r\n"
6858 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236859 };
6860
6861 MockRead data_reads1[] = {
6862 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6863 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6864 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066865 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236866 };
6867
6868 // Resend with authorization (username=foo, password=bar)
6869 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236870 MockWrite(
6871 "GET /x/y/z HTTP/1.1\r\n"
6872 "Host: www.example.org\r\n"
6873 "Connection: keep-alive\r\n"
6874 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236875 };
6876
6877 // Sever accepts the authorization.
6878 MockRead data_reads2[] = {
6879 MockRead("HTTP/1.0 200 OK\r\n"),
6880 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066881 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236882 };
6883
[email protected]31a2bfe2010-02-09 08:03:396884 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6885 data_writes1, arraysize(data_writes1));
6886 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6887 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076888 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6889 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236890
[email protected]49639fa2011-12-20 23:22:416891 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236892
[email protected]49639fa2011-12-20 23:22:416893 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426894 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236895
6896 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426897 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236898
[email protected]1c773ea12009-04-28 19:58:426899 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526900 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046901 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:236902
[email protected]49639fa2011-12-20 23:22:416903 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:236904
[email protected]49639fa2011-12-20 23:22:416905 rv = trans->RestartWithAuth(
6906 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426907 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236908
6909 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426910 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236911
6912 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526913 ASSERT_TRUE(response);
6914 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:236915 EXPECT_EQ(100, response->headers->GetContentLength());
6916 }
6917
6918 // ------------------------------------------------------------------------
6919
6920 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
6921 {
[email protected]1c773ea12009-04-28 19:58:426922 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:236923 request.method = "GET";
6924 // Note that Transaction 1 was at /x/y/z, so this is in the same
6925 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:236926 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]f9ee6b52008-11-08 06:46:236927 request.load_flags = 0;
6928
danakj1fd259a02016-04-16 03:17:096929 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:506930 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:276931
[email protected]f9ee6b52008-11-08 06:46:236932 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236933 MockWrite(
6934 "GET /x/y/a/b HTTP/1.1\r\n"
6935 "Host: www.example.org\r\n"
6936 "Connection: keep-alive\r\n"
6937 // Send preemptive authorization for MyRealm1
6938 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236939 };
6940
6941 // The server didn't like the preemptive authorization, and
6942 // challenges us for a different realm (MyRealm2).
6943 MockRead data_reads1[] = {
6944 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6945 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
6946 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066947 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:236948 };
6949
6950 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
6951 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236952 MockWrite(
6953 "GET /x/y/a/b HTTP/1.1\r\n"
6954 "Host: www.example.org\r\n"
6955 "Connection: keep-alive\r\n"
6956 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236957 };
6958
6959 // Sever accepts the authorization.
6960 MockRead data_reads2[] = {
6961 MockRead("HTTP/1.0 200 OK\r\n"),
6962 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066963 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:236964 };
6965
[email protected]31a2bfe2010-02-09 08:03:396966 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
6967 data_writes1, arraysize(data_writes1));
6968 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
6969 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:076970 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6971 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:236972
[email protected]49639fa2011-12-20 23:22:416973 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:236974
[email protected]49639fa2011-12-20 23:22:416975 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:426976 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236977
6978 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426979 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236980
[email protected]1c773ea12009-04-28 19:58:426981 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526982 ASSERT_TRUE(response);
6983 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:046984 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:436985 EXPECT_EQ("http://www.example.org",
6986 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:046987 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:196988 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:236989
[email protected]49639fa2011-12-20 23:22:416990 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:236991
[email protected]49639fa2011-12-20 23:22:416992 rv = trans->RestartWithAuth(
6993 AuthCredentials(kFoo2, kBar2), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:426994 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:236995
6996 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:426997 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:236998
6999 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527000 ASSERT_TRUE(response);
7001 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237002 EXPECT_EQ(100, response->headers->GetContentLength());
7003 }
7004
7005 // ------------------------------------------------------------------------
7006
7007 // Transaction 3: Resend a request in MyRealm's protection space --
7008 // succeed with preemptive authorization.
7009 {
[email protected]1c773ea12009-04-28 19:58:427010 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237011 request.method = "GET";
bncce36dca22015-04-21 22:11:237012 request.url = GURL("http://www.example.org/x/y/z2");
[email protected]f9ee6b52008-11-08 06:46:237013 request.load_flags = 0;
7014
danakj1fd259a02016-04-16 03:17:097015 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507016 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277017
[email protected]f9ee6b52008-11-08 06:46:237018 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237019 MockWrite(
7020 "GET /x/y/z2 HTTP/1.1\r\n"
7021 "Host: www.example.org\r\n"
7022 "Connection: keep-alive\r\n"
7023 // The authorization for MyRealm1 gets sent preemptively
7024 // (since the url is in the same protection space)
7025 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237026 };
7027
7028 // Sever accepts the preemptive authorization
7029 MockRead data_reads1[] = {
7030 MockRead("HTTP/1.0 200 OK\r\n"),
7031 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067032 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237033 };
7034
[email protected]31a2bfe2010-02-09 08:03:397035 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7036 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077037 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:237038
[email protected]49639fa2011-12-20 23:22:417039 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237040
[email protected]49639fa2011-12-20 23:22:417041 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427042 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:237043
7044 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:427045 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:237046
[email protected]1c773ea12009-04-28 19:58:427047 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527048 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:237049
wezca1070932016-05-26 20:30:527050 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237051 EXPECT_EQ(100, response->headers->GetContentLength());
7052 }
7053
7054 // ------------------------------------------------------------------------
7055
7056 // Transaction 4: request another URL in MyRealm (however the
7057 // url is not known to belong to the protection space, so no pre-auth).
7058 {
[email protected]1c773ea12009-04-28 19:58:427059 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237060 request.method = "GET";
bncce36dca22015-04-21 22:11:237061 request.url = GURL("http://www.example.org/x/1");
[email protected]f9ee6b52008-11-08 06:46:237062 request.load_flags = 0;
7063
danakj1fd259a02016-04-16 03:17:097064 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507065 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277066
[email protected]f9ee6b52008-11-08 06:46:237067 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237068 MockWrite(
7069 "GET /x/1 HTTP/1.1\r\n"
7070 "Host: www.example.org\r\n"
7071 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237072 };
7073
7074 MockRead data_reads1[] = {
7075 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7076 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7077 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067078 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237079 };
7080
7081 // Resend with authorization from MyRealm's cache.
7082 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237083 MockWrite(
7084 "GET /x/1 HTTP/1.1\r\n"
7085 "Host: www.example.org\r\n"
7086 "Connection: keep-alive\r\n"
7087 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237088 };
7089
7090 // Sever accepts the authorization.
7091 MockRead data_reads2[] = {
7092 MockRead("HTTP/1.0 200 OK\r\n"),
7093 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067094 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237095 };
7096
[email protected]31a2bfe2010-02-09 08:03:397097 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7098 data_writes1, arraysize(data_writes1));
7099 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7100 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077101 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7102 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237103
[email protected]49639fa2011-12-20 23:22:417104 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237105
[email protected]49639fa2011-12-20 23:22:417106 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427107 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:237108
7109 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:427110 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:237111
[email protected]0757e7702009-03-27 04:00:227112 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417113 TestCompletionCallback callback2;
7114 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:427115 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:227116 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:427117 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:227118 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
7119
[email protected]1c773ea12009-04-28 19:58:427120 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527121 ASSERT_TRUE(response);
7122 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237123 EXPECT_EQ(100, response->headers->GetContentLength());
7124 }
7125
7126 // ------------------------------------------------------------------------
7127
7128 // Transaction 5: request a URL in MyRealm, but the server rejects the
7129 // cached identity. Should invalidate and re-prompt.
7130 {
[email protected]1c773ea12009-04-28 19:58:427131 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237132 request.method = "GET";
bncce36dca22015-04-21 22:11:237133 request.url = GURL("http://www.example.org/p/q/t");
[email protected]f9ee6b52008-11-08 06:46:237134 request.load_flags = 0;
7135
danakj1fd259a02016-04-16 03:17:097136 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507137 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277138
[email protected]f9ee6b52008-11-08 06:46:237139 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237140 MockWrite(
7141 "GET /p/q/t HTTP/1.1\r\n"
7142 "Host: www.example.org\r\n"
7143 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237144 };
7145
7146 MockRead data_reads1[] = {
7147 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7148 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7149 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067150 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237151 };
7152
7153 // Resend with authorization from cache for MyRealm.
7154 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237155 MockWrite(
7156 "GET /p/q/t HTTP/1.1\r\n"
7157 "Host: www.example.org\r\n"
7158 "Connection: keep-alive\r\n"
7159 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237160 };
7161
7162 // Sever rejects the authorization.
7163 MockRead data_reads2[] = {
7164 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7165 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7166 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067167 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237168 };
7169
7170 // At this point we should prompt for new credentials for MyRealm.
7171 // Restart with username=foo3, password=foo4.
7172 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237173 MockWrite(
7174 "GET /p/q/t HTTP/1.1\r\n"
7175 "Host: www.example.org\r\n"
7176 "Connection: keep-alive\r\n"
7177 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237178 };
7179
7180 // Sever accepts the authorization.
7181 MockRead data_reads3[] = {
7182 MockRead("HTTP/1.0 200 OK\r\n"),
7183 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067184 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237185 };
7186
[email protected]31a2bfe2010-02-09 08:03:397187 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7188 data_writes1, arraysize(data_writes1));
7189 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7190 data_writes2, arraysize(data_writes2));
7191 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
7192 data_writes3, arraysize(data_writes3));
[email protected]bb88e1d32013-05-03 23:11:077193 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7194 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7195 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:237196
[email protected]49639fa2011-12-20 23:22:417197 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237198
[email protected]49639fa2011-12-20 23:22:417199 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:427200 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:237201
7202 rv = callback1.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:427203 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:237204
[email protected]0757e7702009-03-27 04:00:227205 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417206 TestCompletionCallback callback2;
7207 rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
[email protected]1c773ea12009-04-28 19:58:427208 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]0757e7702009-03-27 04:00:227209 rv = callback2.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:427210 EXPECT_EQ(OK, rv);
[email protected]0757e7702009-03-27 04:00:227211 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
7212
[email protected]1c773ea12009-04-28 19:58:427213 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527214 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047215 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237216
[email protected]49639fa2011-12-20 23:22:417217 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:237218
[email protected]49639fa2011-12-20 23:22:417219 rv = trans->RestartWithAuth(
7220 AuthCredentials(kFoo3, kBar3), callback3.callback());
[email protected]1c773ea12009-04-28 19:58:427221 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]f9ee6b52008-11-08 06:46:237222
[email protected]0757e7702009-03-27 04:00:227223 rv = callback3.WaitForResult();
[email protected]1c773ea12009-04-28 19:58:427224 EXPECT_EQ(OK, rv);
[email protected]f9ee6b52008-11-08 06:46:237225
7226 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527227 ASSERT_TRUE(response);
7228 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:237229 EXPECT_EQ(100, response->headers->GetContentLength());
7230 }
7231}
[email protected]89ceba9a2009-03-21 03:46:067232
[email protected]3c32c5f2010-05-18 15:18:127233// Tests that nonce count increments when multiple auth attempts
7234// are started with the same nonce.
[email protected]23e482282013-06-14 16:08:027235TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:447236 HttpAuthHandlerDigest::Factory* digest_factory =
7237 new HttpAuthHandlerDigest::Factory();
7238 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
7239 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
7240 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:077241 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:097242 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:127243
7244 // Transaction 1: authenticate (foo, bar) on MyRealm1
7245 {
[email protected]3c32c5f2010-05-18 15:18:127246 HttpRequestInfo request;
7247 request.method = "GET";
bncce36dca22015-04-21 22:11:237248 request.url = GURL("http://www.example.org/x/y/z");
[email protected]3c32c5f2010-05-18 15:18:127249 request.load_flags = 0;
7250
danakj1fd259a02016-04-16 03:17:097251 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507252 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277253
[email protected]3c32c5f2010-05-18 15:18:127254 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237255 MockWrite(
7256 "GET /x/y/z HTTP/1.1\r\n"
7257 "Host: www.example.org\r\n"
7258 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127259 };
7260
7261 MockRead data_reads1[] = {
7262 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7263 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
7264 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067265 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127266 };
7267
7268 // Resend with authorization (username=foo, password=bar)
7269 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237270 MockWrite(
7271 "GET /x/y/z HTTP/1.1\r\n"
7272 "Host: www.example.org\r\n"
7273 "Connection: keep-alive\r\n"
7274 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7275 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
7276 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
7277 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127278 };
7279
7280 // Sever accepts the authorization.
7281 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:087282 MockRead("HTTP/1.0 200 OK\r\n"),
7283 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127284 };
7285
7286 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7287 data_writes1, arraysize(data_writes1));
7288 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
7289 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:077290 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7291 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:127292
[email protected]49639fa2011-12-20 23:22:417293 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127294
[email protected]49639fa2011-12-20 23:22:417295 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:127296 EXPECT_EQ(ERR_IO_PENDING, rv);
7297
7298 rv = callback1.WaitForResult();
7299 EXPECT_EQ(OK, rv);
7300
7301 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527302 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047303 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:127304
[email protected]49639fa2011-12-20 23:22:417305 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:127306
[email protected]49639fa2011-12-20 23:22:417307 rv = trans->RestartWithAuth(
7308 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]3c32c5f2010-05-18 15:18:127309 EXPECT_EQ(ERR_IO_PENDING, rv);
7310
7311 rv = callback2.WaitForResult();
7312 EXPECT_EQ(OK, rv);
7313
7314 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527315 ASSERT_TRUE(response);
7316 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127317 }
7318
7319 // ------------------------------------------------------------------------
7320
7321 // Transaction 2: Request another resource in digestive's protection space.
7322 // This will preemptively add an Authorization header which should have an
7323 // "nc" value of 2 (as compared to 1 in the first use.
7324 {
[email protected]3c32c5f2010-05-18 15:18:127325 HttpRequestInfo request;
7326 request.method = "GET";
7327 // Note that Transaction 1 was at /x/y/z, so this is in the same
7328 // protection space as digest.
bncce36dca22015-04-21 22:11:237329 request.url = GURL("http://www.example.org/x/y/a/b");
[email protected]3c32c5f2010-05-18 15:18:127330 request.load_flags = 0;
7331
danakj1fd259a02016-04-16 03:17:097332 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507333 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277334
[email protected]3c32c5f2010-05-18 15:18:127335 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237336 MockWrite(
7337 "GET /x/y/a/b HTTP/1.1\r\n"
7338 "Host: www.example.org\r\n"
7339 "Connection: keep-alive\r\n"
7340 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
7341 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
7342 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
7343 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:127344 };
7345
7346 // Sever accepts the authorization.
7347 MockRead data_reads1[] = {
7348 MockRead("HTTP/1.0 200 OK\r\n"),
7349 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067350 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:127351 };
7352
7353 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
7354 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:077355 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:127356
[email protected]49639fa2011-12-20 23:22:417357 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:127358
[email protected]49639fa2011-12-20 23:22:417359 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]3c32c5f2010-05-18 15:18:127360 EXPECT_EQ(ERR_IO_PENDING, rv);
7361
7362 rv = callback1.WaitForResult();
7363 EXPECT_EQ(OK, rv);
7364
7365 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527366 ASSERT_TRUE(response);
7367 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:127368 }
7369}
7370
[email protected]89ceba9a2009-03-21 03:46:067371// Test the ResetStateForRestart() private method.
[email protected]23e482282013-06-14 16:08:027372TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:067373 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:097374 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7375 std::unique_ptr<HttpNetworkTransaction> trans(
dcheng48459ac22014-08-26 00:46:417376 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]89ceba9a2009-03-21 03:46:067377
7378 // Setup some state (which we expect ResetStateForRestart() will clear).
[email protected]89ceba9a2009-03-21 03:46:067379 trans->read_buf_ = new IOBuffer(15);
7380 trans->read_buf_len_ = 15;
[email protected]b94f92d2010-10-27 16:45:207381 trans->request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:067382
7383 // Setup state in response_
[email protected]a7e41312009-12-16 23:18:147384 HttpResponseInfo* response = &trans->response_;
[email protected]0877e3d2009-10-17 22:29:577385 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:087386 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:577387 response->response_time = base::Time::Now();
7388 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:067389
7390 { // Setup state for response_.vary_data
7391 HttpRequestInfo request;
7392 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
7393 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:277394 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:437395 request.extra_headers.SetHeader("Foo", "1");
7396 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:507397 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:067398 }
7399
7400 // Cause the above state to be reset.
7401 trans->ResetStateForRestart();
7402
7403 // Verify that the state that needed to be reset, has been reset.
wezca1070932016-05-26 20:30:527404 EXPECT_FALSE(trans->read_buf_);
[email protected]89ceba9a2009-03-21 03:46:067405 EXPECT_EQ(0, trans->read_buf_len_);
[email protected]b94f92d2010-10-27 16:45:207406 EXPECT_TRUE(trans->request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:527407 EXPECT_FALSE(response->auth_challenge);
7408 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:047409 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:087410 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:577411 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:067412}
7413
[email protected]bacff652009-03-31 17:50:337414// Test HTTPS connections to a site with a bad certificate
[email protected]23e482282013-06-14 16:08:027415TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:337416 HttpRequestInfo request;
7417 request.method = "GET";
bncce36dca22015-04-21 22:11:237418 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337419 request.load_flags = 0;
7420
danakj1fd259a02016-04-16 03:17:097421 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7422 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417423 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:277424
[email protected]bacff652009-03-31 17:50:337425 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237426 MockWrite(
7427 "GET / HTTP/1.1\r\n"
7428 "Host: www.example.org\r\n"
7429 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337430 };
7431
7432 MockRead data_reads[] = {
7433 MockRead("HTTP/1.0 200 OK\r\n"),
7434 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7435 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067436 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337437 };
7438
[email protected]5ecc992a42009-11-11 01:41:597439 StaticSocketDataProvider ssl_bad_certificate;
[email protected]31a2bfe2010-02-09 08:03:397440 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7441 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067442 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7443 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337444
[email protected]bb88e1d32013-05-03 23:11:077445 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7446 session_deps_.socket_factory->AddSocketDataProvider(&data);
7447 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7448 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337449
[email protected]49639fa2011-12-20 23:22:417450 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337451
[email protected]49639fa2011-12-20 23:22:417452 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:337453 EXPECT_EQ(ERR_IO_PENDING, rv);
7454
7455 rv = callback.WaitForResult();
7456 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7457
[email protected]49639fa2011-12-20 23:22:417458 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:337459 EXPECT_EQ(ERR_IO_PENDING, rv);
7460
7461 rv = callback.WaitForResult();
7462 EXPECT_EQ(OK, rv);
7463
7464 const HttpResponseInfo* response = trans->GetResponseInfo();
7465
wezca1070932016-05-26 20:30:527466 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337467 EXPECT_EQ(100, response->headers->GetContentLength());
7468}
7469
7470// Test HTTPS connections to a site with a bad certificate, going through a
7471// proxy
[email protected]23e482282013-06-14 16:08:027472TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
rdsmith82957ad2015-09-16 19:42:037473 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]bacff652009-03-31 17:50:337474
7475 HttpRequestInfo request;
7476 request.method = "GET";
bncce36dca22015-04-21 22:11:237477 request.url = GURL("https://www.example.org/");
[email protected]bacff652009-03-31 17:50:337478 request.load_flags = 0;
7479
7480 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:177481 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7482 "Host: www.example.org:443\r\n"
7483 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337484 };
7485
7486 MockRead proxy_reads[] = {
7487 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067488 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:337489 };
7490
7491 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177492 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7493 "Host: www.example.org:443\r\n"
7494 "Proxy-Connection: keep-alive\r\n\r\n"),
7495 MockWrite("GET / HTTP/1.1\r\n"
7496 "Host: www.example.org\r\n"
7497 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:337498 };
7499
7500 MockRead data_reads[] = {
7501 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7502 MockRead("HTTP/1.0 200 OK\r\n"),
7503 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7504 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067505 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:337506 };
7507
[email protected]31a2bfe2010-02-09 08:03:397508 StaticSocketDataProvider ssl_bad_certificate(
7509 proxy_reads, arraysize(proxy_reads),
7510 proxy_writes, arraysize(proxy_writes));
7511 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7512 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067513 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
7514 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:337515
[email protected]bb88e1d32013-05-03 23:11:077516 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
7517 session_deps_.socket_factory->AddSocketDataProvider(&data);
7518 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
7519 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:337520
[email protected]49639fa2011-12-20 23:22:417521 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:337522
7523 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:077524 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:337525
danakj1fd259a02016-04-16 03:17:097526 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7527 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417528 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bacff652009-03-31 17:50:337529
[email protected]49639fa2011-12-20 23:22:417530 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]bacff652009-03-31 17:50:337531 EXPECT_EQ(ERR_IO_PENDING, rv);
7532
7533 rv = callback.WaitForResult();
7534 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
7535
[email protected]49639fa2011-12-20 23:22:417536 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]bacff652009-03-31 17:50:337537 EXPECT_EQ(ERR_IO_PENDING, rv);
7538
7539 rv = callback.WaitForResult();
7540 EXPECT_EQ(OK, rv);
7541
7542 const HttpResponseInfo* response = trans->GetResponseInfo();
7543
wezca1070932016-05-26 20:30:527544 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:337545 EXPECT_EQ(100, response->headers->GetContentLength());
7546 }
7547}
7548
[email protected]2df19bb2010-08-25 20:13:467549
7550// Test HTTPS connections to a site, going through an HTTPS proxy
[email protected]23e482282013-06-14 16:08:027551TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037552 session_deps_.proxy_service =
7553 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517554 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077555 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:467556
7557 HttpRequestInfo request;
7558 request.method = "GET";
bncce36dca22015-04-21 22:11:237559 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:467560 request.load_flags = 0;
7561
7562 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177563 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7564 "Host: www.example.org:443\r\n"
7565 "Proxy-Connection: keep-alive\r\n\r\n"),
7566 MockWrite("GET / HTTP/1.1\r\n"
7567 "Host: www.example.org\r\n"
7568 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:467569 };
7570
7571 MockRead data_reads[] = {
7572 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
7573 MockRead("HTTP/1.1 200 OK\r\n"),
7574 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7575 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067576 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:467577 };
7578
7579 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7580 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067581 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
7582 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:467583
[email protected]bb88e1d32013-05-03 23:11:077584 session_deps_.socket_factory->AddSocketDataProvider(&data);
7585 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
7586 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:467587
[email protected]49639fa2011-12-20 23:22:417588 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:467589
danakj1fd259a02016-04-16 03:17:097590 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7591 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417592 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:467593
[email protected]49639fa2011-12-20 23:22:417594 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:467595 EXPECT_EQ(ERR_IO_PENDING, rv);
7596
7597 rv = callback.WaitForResult();
7598 EXPECT_EQ(OK, rv);
7599 const HttpResponseInfo* response = trans->GetResponseInfo();
7600
wezca1070932016-05-26 20:30:527601 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:467602
7603 EXPECT_TRUE(response->headers->IsKeepAlive());
7604 EXPECT_EQ(200, response->headers->response_code());
7605 EXPECT_EQ(100, response->headers->GetContentLength());
7606 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:207607
7608 LoadTimingInfo load_timing_info;
7609 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7610 TestLoadTimingNotReusedWithPac(load_timing_info,
7611 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:467612}
7613
[email protected]511f6f52010-12-17 03:58:297614// Test an HTTPS Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:027615TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037616 session_deps_.proxy_service =
7617 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:517618 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:077619 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:297620
7621 HttpRequestInfo request;
7622 request.method = "GET";
bncce36dca22015-04-21 22:11:237623 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297624 request.load_flags = 0;
7625
7626 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177627 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7628 "Host: www.example.org:443\r\n"
7629 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297630 };
7631
7632 MockRead data_reads[] = {
7633 MockRead("HTTP/1.1 302 Redirect\r\n"),
7634 MockRead("Location: http://login.example.com/\r\n"),
7635 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067636 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297637 };
7638
7639 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7640 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067641 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297642
[email protected]bb88e1d32013-05-03 23:11:077643 session_deps_.socket_factory->AddSocketDataProvider(&data);
7644 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297645
[email protected]49639fa2011-12-20 23:22:417646 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297647
danakj1fd259a02016-04-16 03:17:097648 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7649 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417650 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297651
[email protected]49639fa2011-12-20 23:22:417652 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297653 EXPECT_EQ(ERR_IO_PENDING, rv);
7654
7655 rv = callback.WaitForResult();
7656 EXPECT_EQ(OK, rv);
7657 const HttpResponseInfo* response = trans->GetResponseInfo();
7658
wezca1070932016-05-26 20:30:527659 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297660
7661 EXPECT_EQ(302, response->headers->response_code());
7662 std::string url;
7663 EXPECT_TRUE(response->headers->IsRedirect(&url));
7664 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:207665
7666 // In the case of redirects from proxies, HttpNetworkTransaction returns
7667 // timing for the proxy connection instead of the connection to the host,
7668 // and no send / receive times.
7669 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
7670 LoadTimingInfo load_timing_info;
7671 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7672
7673 EXPECT_FALSE(load_timing_info.socket_reused);
ttuttle859dc7a2015-04-23 19:42:297674 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:207675
7676 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
7677 EXPECT_LE(load_timing_info.proxy_resolve_start,
7678 load_timing_info.proxy_resolve_end);
7679 EXPECT_LE(load_timing_info.proxy_resolve_end,
7680 load_timing_info.connect_timing.connect_start);
7681 ExpectConnectTimingHasTimes(
7682 load_timing_info.connect_timing,
7683 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
7684
7685 EXPECT_TRUE(load_timing_info.send_start.is_null());
7686 EXPECT_TRUE(load_timing_info.send_end.is_null());
7687 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:297688}
7689
7690// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
[email protected]23e482282013-06-14 16:08:027691TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037692 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297693
7694 HttpRequestInfo request;
7695 request.method = "GET";
bncce36dca22015-04-21 22:11:237696 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297697 request.load_flags = 0;
7698
danakj1fd259a02016-04-16 03:17:097699 std::unique_ptr<SpdySerializedFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237700 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:097701 std::unique_ptr<SpdySerializedFrame> goaway(
[email protected]c10b20852013-05-15 21:29:207702 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297703 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:137704 CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
7705 CreateMockWrite(*goaway.get(), 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:297706 };
7707
7708 static const char* const kExtraHeaders[] = {
7709 "location",
7710 "http://login.example.com/",
7711 };
danakj1fd259a02016-04-16 03:17:097712 std::unique_ptr<SpdySerializedFrame> resp(
7713 spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
7714 arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:297715 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:137716 CreateMockRead(*resp.get(), 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:297717 };
7718
rch8e6c6c42015-05-01 14:05:137719 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7720 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067721 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
rdsmithebb50aa2015-11-12 03:44:387722 proxy_ssl.SetNextProto(GetProtocol());
[email protected]511f6f52010-12-17 03:58:297723
[email protected]bb88e1d32013-05-03 23:11:077724 session_deps_.socket_factory->AddSocketDataProvider(&data);
7725 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297726
[email protected]49639fa2011-12-20 23:22:417727 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297728
danakj1fd259a02016-04-16 03:17:097729 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7730 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417731 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297732
[email protected]49639fa2011-12-20 23:22:417733 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297734 EXPECT_EQ(ERR_IO_PENDING, rv);
7735
7736 rv = callback.WaitForResult();
7737 EXPECT_EQ(OK, rv);
7738 const HttpResponseInfo* response = trans->GetResponseInfo();
7739
wezca1070932016-05-26 20:30:527740 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:297741
7742 EXPECT_EQ(302, response->headers->response_code());
7743 std::string url;
7744 EXPECT_TRUE(response->headers->IsRedirect(&url));
7745 EXPECT_EQ("http://login.example.com/", url);
7746}
7747
[email protected]4eddbc732012-08-09 05:40:177748// Test that an HTTPS proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:027749TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:177750 ErrorResponseToHttpsConnectViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:037751 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297752
7753 HttpRequestInfo request;
7754 request.method = "GET";
bncce36dca22015-04-21 22:11:237755 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297756 request.load_flags = 0;
7757
7758 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:177759 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7760 "Host: www.example.org:443\r\n"
7761 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:297762 };
7763
7764 MockRead data_reads[] = {
7765 MockRead("HTTP/1.1 404 Not Found\r\n"),
7766 MockRead("Content-Length: 23\r\n\r\n"),
7767 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:067768 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:297769 };
7770
7771 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
7772 data_writes, arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067773 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:297774
[email protected]bb88e1d32013-05-03 23:11:077775 session_deps_.socket_factory->AddSocketDataProvider(&data);
7776 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297777
[email protected]49639fa2011-12-20 23:22:417778 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297779
danakj1fd259a02016-04-16 03:17:097780 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7781 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417782 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297783
[email protected]49639fa2011-12-20 23:22:417784 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297785 EXPECT_EQ(ERR_IO_PENDING, rv);
7786
7787 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:177788 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:297789
ttuttle960fcbf2016-04-19 13:26:327790 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297791}
7792
[email protected]4eddbc732012-08-09 05:40:177793// Test that a SPDY proxy's response to a CONNECT request is filtered.
[email protected]23e482282013-06-14 16:08:027794TEST_P(HttpNetworkTransactionTest,
[email protected]4eddbc732012-08-09 05:40:177795 ErrorResponseToHttpsConnectViaSpdyProxy) {
rdsmith82957ad2015-09-16 19:42:037796 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]511f6f52010-12-17 03:58:297797
7798 HttpRequestInfo request;
7799 request.method = "GET";
bncce36dca22015-04-21 22:11:237800 request.url = GURL("https://www.example.org/");
[email protected]511f6f52010-12-17 03:58:297801 request.load_flags = 0;
7802
danakj1fd259a02016-04-16 03:17:097803 std::unique_ptr<SpdySerializedFrame> conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237804 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:097805 std::unique_ptr<SpdySerializedFrame> rst(
[email protected]c10b20852013-05-15 21:29:207806 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
[email protected]511f6f52010-12-17 03:58:297807 MockWrite data_writes[] = {
rch8e6c6c42015-05-01 14:05:137808 CreateMockWrite(*conn.get(), 0), CreateMockWrite(*rst.get(), 3),
[email protected]511f6f52010-12-17 03:58:297809 };
7810
7811 static const char* const kExtraHeaders[] = {
7812 "location",
7813 "http://login.example.com/",
7814 };
danakj1fd259a02016-04-16 03:17:097815 std::unique_ptr<SpdySerializedFrame> resp(
7816 spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
7817 arraysize(kExtraHeaders) / 2, 1));
7818 std::unique_ptr<SpdySerializedFrame> body(spdy_util_.ConstructSpdyBodyFrame(
bncb03b1092016-04-06 11:19:557819 1, "The host does not exist", 23, true));
[email protected]511f6f52010-12-17 03:58:297820 MockRead data_reads[] = {
rch8e6c6c42015-05-01 14:05:137821 CreateMockRead(*resp.get(), 1),
7822 CreateMockRead(*body.get(), 2),
7823 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:297824 };
7825
rch8e6c6c42015-05-01 14:05:137826 SequencedSocketData data(data_reads, arraysize(data_reads), data_writes,
7827 arraysize(data_writes));
[email protected]8ddf8322012-02-23 18:08:067828 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
rdsmithebb50aa2015-11-12 03:44:387829 proxy_ssl.SetNextProto(GetProtocol());
[email protected]511f6f52010-12-17 03:58:297830
[email protected]bb88e1d32013-05-03 23:11:077831 session_deps_.socket_factory->AddSocketDataProvider(&data);
7832 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:297833
[email protected]49639fa2011-12-20 23:22:417834 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:297835
danakj1fd259a02016-04-16 03:17:097836 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7837 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:417838 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]511f6f52010-12-17 03:58:297839
[email protected]49639fa2011-12-20 23:22:417840 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]511f6f52010-12-17 03:58:297841 EXPECT_EQ(ERR_IO_PENDING, rv);
7842
7843 rv = callback.WaitForResult();
[email protected]4eddbc732012-08-09 05:40:177844 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
[email protected]511f6f52010-12-17 03:58:297845
ttuttle960fcbf2016-04-19 13:26:327846 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:297847}
7848
[email protected]0c5fb722012-02-28 11:50:357849// Test the request-challenge-retry sequence for basic auth, through
7850// a SPDY proxy over a single SPDY session.
[email protected]23e482282013-06-14 16:08:027851TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:357852 HttpRequestInfo request;
7853 request.method = "GET";
bncce36dca22015-04-21 22:11:237854 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:357855 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:297856 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
[email protected]0c5fb722012-02-28 11:50:357857
7858 // Configure against https proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:037859 session_deps_.proxy_service =
7860 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70");
vishal.b62985ca92015-04-17 08:45:517861 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:077862 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:097863 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:357864
7865 // Since we have proxy, should try to establish tunnel.
danakj1fd259a02016-04-16 03:17:097866 std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:237867 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
danakj1fd259a02016-04-16 03:17:097868 std::unique_ptr<SpdySerializedFrame> rst(
[email protected]c10b20852013-05-15 21:29:207869 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
rdsmithebb50aa2015-11-12 03:44:387870 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:357871
7872 // After calling trans->RestartWithAuth(), this is the request we should
7873 // be issuing -- the final header line contains the credentials.
7874 const char* const kAuthCredentials[] = {
7875 "proxy-authorization", "Basic Zm9vOmJhcg==",
7876 };
danakj1fd259a02016-04-16 03:17:097877 std::unique_ptr<SpdySerializedFrame> connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:347878 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:237879 HostPortPair("www.example.org", 443)));
7880 // fetch https://www.example.org/ via HTTP
7881 const char get[] =
7882 "GET / HTTP/1.1\r\n"
7883 "Host: www.example.org\r\n"
7884 "Connection: keep-alive\r\n\r\n";
danakj1fd259a02016-04-16 03:17:097885 std::unique_ptr<SpdySerializedFrame> wrapped_get(
[email protected]23e482282013-06-14 16:08:027886 spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
[email protected]0c5fb722012-02-28 11:50:357887
7888 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:137889 CreateMockWrite(*req, 0, ASYNC),
7890 CreateMockWrite(*rst, 2, ASYNC),
7891 CreateMockWrite(*connect2, 3),
7892 CreateMockWrite(*wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:357893 };
7894
7895 // The proxy responds to the connect with a 407, using a persistent
7896 // connection.
thestig9d3bb0c2015-01-24 00:49:517897 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:357898 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:357899 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
7900 };
danakj1fd259a02016-04-16 03:17:097901 std::unique_ptr<SpdySerializedFrame> conn_auth_resp(
bncb03b1092016-04-06 11:19:557902 spdy_util_.ConstructSpdySynReplyError(kAuthStatus, kAuthChallenge,
7903 arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:357904
danakj1fd259a02016-04-16 03:17:097905 std::unique_ptr<SpdySerializedFrame> conn_resp(
[email protected]23e482282013-06-14 16:08:027906 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:357907 const char resp[] = "HTTP/1.1 200 OK\r\n"
7908 "Content-Length: 5\r\n\r\n";
7909
danakj1fd259a02016-04-16 03:17:097910 std::unique_ptr<SpdySerializedFrame> wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:027911 spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
danakj1fd259a02016-04-16 03:17:097912 std::unique_ptr<SpdySerializedFrame> wrapped_body(
[email protected]23e482282013-06-14 16:08:027913 spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
[email protected]0c5fb722012-02-28 11:50:357914 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:137915 CreateMockRead(*conn_auth_resp, 1, ASYNC),
7916 CreateMockRead(*conn_resp, 4, ASYNC),
7917 CreateMockRead(*wrapped_get_resp, 6, ASYNC),
7918 CreateMockRead(*wrapped_body, 7, ASYNC),
7919 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:357920 };
7921
rch8e6c6c42015-05-01 14:05:137922 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
7923 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:077924 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:357925 // Negotiate SPDY to the proxy
7926 SSLSocketDataProvider proxy(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:387927 proxy.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:077928 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:357929 // Vanilla SSL to the server
7930 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077931 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:357932
7933 TestCompletionCallback callback1;
7934
danakj1fd259a02016-04-16 03:17:097935 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:507936 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0c5fb722012-02-28 11:50:357937
7938 int rv = trans->Start(&request, callback1.callback(), log.bound());
7939 EXPECT_EQ(ERR_IO_PENDING, rv);
7940
7941 rv = callback1.WaitForResult();
7942 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:467943 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:357944 log.GetEntries(&entries);
7945 size_t pos = ExpectLogContainsSomewhere(
7946 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
7947 NetLog::PHASE_NONE);
7948 ExpectLogContainsSomewhere(
7949 entries, pos,
7950 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
7951 NetLog::PHASE_NONE);
7952
7953 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527954 ASSERT_TRUE(response);
7955 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:357956 EXPECT_EQ(407, response->headers->response_code());
7957 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:527958 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:437959 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:357960
7961 TestCompletionCallback callback2;
7962
7963 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
7964 callback2.callback());
7965 EXPECT_EQ(ERR_IO_PENDING, rv);
7966
7967 rv = callback2.WaitForResult();
7968 EXPECT_EQ(OK, rv);
7969
7970 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527971 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:357972
7973 EXPECT_TRUE(response->headers->IsKeepAlive());
7974 EXPECT_EQ(200, response->headers->response_code());
7975 EXPECT_EQ(5, response->headers->GetContentLength());
7976 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
7977
7978 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:527979 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:357980
[email protected]029c83b62013-01-24 05:28:207981 LoadTimingInfo load_timing_info;
7982 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
7983 TestLoadTimingNotReusedWithPac(load_timing_info,
7984 CONNECT_TIMING_HAS_SSL_TIMES);
7985
[email protected]0c5fb722012-02-28 11:50:357986 trans.reset();
7987 session->CloseAllConnections();
7988}
7989
[email protected]7c6f7ba2012-04-03 04:09:297990// Test that an explicitly trusted SPDY proxy can push a resource from an
7991// origin that is different from that of its associated resource.
tbansal28e68f82016-02-04 02:56:157992TEST_P(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
7993 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:097994 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:157995 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
7996 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:297997 HttpRequestInfo request;
7998 HttpRequestInfo push_request;
7999
[email protected]7c6f7ba2012-04-03 04:09:298000 request.method = "GET";
bncce36dca22015-04-21 22:11:238001 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:298002 push_request.method = "GET";
8003 push_request.url = GURL("http://www.another-origin.com/foo.dat");
8004
tbansal28e68f82016-02-04 02:56:158005 // Configure against https proxy server "myproxy:443".
rdsmith82957ad2015-09-16 19:42:038006 session_deps_.proxy_service =
tbansal28e68f82016-02-04 02:56:158007 ProxyService::CreateFixedFromPacResult("HTTPS myproxy:443");
vishal.b62985ca92015-04-17 08:45:518008 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078009 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508010
tbansal28e68f82016-02-04 02:56:158011 session_deps_.proxy_delegate.reset(proxy_delegate.release());
[email protected]61b4efc2012-04-27 18:12:508012
danakj1fd259a02016-04-16 03:17:098013 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:298014
danakj1fd259a02016-04-16 03:17:098015 std::unique_ptr<SpdySerializedFrame> stream1_syn(
bnc38dcd392016-02-09 23:19:498016 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
[email protected]7c6f7ba2012-04-03 04:09:298017
8018 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:138019 CreateMockWrite(*stream1_syn, 0, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:298020 };
8021
danakj1fd259a02016-04-16 03:17:098022 std::unique_ptr<SpdySerializedFrame> stream1_reply(
bncb03b1092016-04-06 11:19:558023 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:298024
danakj1fd259a02016-04-16 03:17:098025 std::unique_ptr<SpdySerializedFrame> stream1_body(
bncb03b1092016-04-06 11:19:558026 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:298027
danakj1fd259a02016-04-16 03:17:098028 std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558029 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
[email protected]8a0fc822013-06-27 20:52:438030 const char kPushedData[] = "pushed";
danakj1fd259a02016-04-16 03:17:098031 std::unique_ptr<SpdySerializedFrame> stream2_body(
bncb03b1092016-04-06 11:19:558032 spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData),
8033 true));
[email protected]7c6f7ba2012-04-03 04:09:298034
8035 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:138036 CreateMockRead(*stream1_reply, 1, ASYNC),
8037 CreateMockRead(*stream2_syn, 2, ASYNC),
8038 CreateMockRead(*stream1_body, 3, ASYNC),
8039 CreateMockRead(*stream2_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598040 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:298041 };
8042
rch8e6c6c42015-05-01 14:05:138043 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8044 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078045 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:298046 // Negotiate SPDY to the proxy
8047 SSLSocketDataProvider proxy(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:388048 proxy.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:078049 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:298050
danakj1fd259a02016-04-16 03:17:098051 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508052 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]7c6f7ba2012-04-03 04:09:298053 TestCompletionCallback callback;
8054 int rv = trans->Start(&request, callback.callback(), log.bound());
8055 EXPECT_EQ(ERR_IO_PENDING, rv);
8056
8057 rv = callback.WaitForResult();
8058 EXPECT_EQ(OK, rv);
8059 const HttpResponseInfo* response = trans->GetResponseInfo();
8060
danakj1fd259a02016-04-16 03:17:098061 std::unique_ptr<HttpTransaction> push_trans(
[email protected]90499482013-06-01 00:39:508062 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8063 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
[email protected]7c6f7ba2012-04-03 04:09:298064 EXPECT_EQ(ERR_IO_PENDING, rv);
8065
8066 rv = callback.WaitForResult();
8067 EXPECT_EQ(OK, rv);
8068 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
8069
wezca1070932016-05-26 20:30:528070 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:298071 EXPECT_TRUE(response->headers->IsKeepAlive());
8072
8073 EXPECT_EQ(200, response->headers->response_code());
8074 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8075
8076 std::string response_data;
8077 rv = ReadTransaction(trans.get(), &response_data);
8078 EXPECT_EQ(OK, rv);
8079 EXPECT_EQ("hello!", response_data);
8080
[email protected]029c83b62013-01-24 05:28:208081 LoadTimingInfo load_timing_info;
8082 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8083 TestLoadTimingNotReusedWithPac(load_timing_info,
8084 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8085
[email protected]7c6f7ba2012-04-03 04:09:298086 // Verify the pushed stream.
wezca1070932016-05-26 20:30:528087 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:298088 EXPECT_EQ(200, push_response->headers->response_code());
8089
8090 rv = ReadTransaction(push_trans.get(), &response_data);
8091 EXPECT_EQ(OK, rv);
8092 EXPECT_EQ("pushed", response_data);
8093
[email protected]029c83b62013-01-24 05:28:208094 LoadTimingInfo push_load_timing_info;
8095 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
8096 TestLoadTimingReusedWithPac(push_load_timing_info);
8097 // The transactions should share a socket ID, despite being for different
8098 // origins.
8099 EXPECT_EQ(load_timing_info.socket_log_id,
8100 push_load_timing_info.socket_log_id);
8101
[email protected]7c6f7ba2012-04-03 04:09:298102 trans.reset();
8103 push_trans.reset();
8104 session->CloseAllConnections();
8105}
8106
[email protected]8c843192012-04-05 07:15:008107// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
[email protected]23e482282013-06-14 16:08:028108TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158109 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098110 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158111 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
8112 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:008113 HttpRequestInfo request;
8114
8115 request.method = "GET";
bncce36dca22015-04-21 22:11:238116 request.url = GURL("http://www.example.org/");
[email protected]8c843192012-04-05 07:15:008117
tbansal28e68f82016-02-04 02:56:158118 session_deps_.proxy_service =
8119 ProxyService::CreateFixed("https://myproxy:443");
vishal.b62985ca92015-04-17 08:45:518120 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078121 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:508122
8123 // Enable cross-origin push.
tbansal28e68f82016-02-04 02:56:158124 session_deps_.proxy_delegate.reset(proxy_delegate.release());
[email protected]61b4efc2012-04-27 18:12:508125
danakj1fd259a02016-04-16 03:17:098126 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:008127
danakj1fd259a02016-04-16 03:17:098128 std::unique_ptr<SpdySerializedFrame> stream1_syn(
bnc38dcd392016-02-09 23:19:498129 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
[email protected]8c843192012-04-05 07:15:008130
danakj1fd259a02016-04-16 03:17:098131 std::unique_ptr<SpdySerializedFrame> push_rst(
[email protected]c10b20852013-05-15 21:29:208132 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:008133
8134 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:138135 CreateMockWrite(*stream1_syn, 0, ASYNC), CreateMockWrite(*push_rst, 3),
[email protected]8c843192012-04-05 07:15:008136 };
8137
danakj1fd259a02016-04-16 03:17:098138 std::unique_ptr<SpdySerializedFrame> stream1_reply(
bncb03b1092016-04-06 11:19:558139 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:008140
danakj1fd259a02016-04-16 03:17:098141 std::unique_ptr<SpdySerializedFrame> stream1_body(
bncb03b1092016-04-06 11:19:558142 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]8c843192012-04-05 07:15:008143
danakj1fd259a02016-04-16 03:17:098144 std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:558145 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:008146
8147 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:138148 CreateMockRead(*stream1_reply, 1, ASYNC),
8149 CreateMockRead(*stream2_syn, 2, ASYNC),
8150 CreateMockRead(*stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:598151 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:008152 };
8153
rch8e6c6c42015-05-01 14:05:138154 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8155 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:078156 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:008157 // Negotiate SPDY to the proxy
8158 SSLSocketDataProvider proxy(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:388159 proxy.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:078160 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:008161
danakj1fd259a02016-04-16 03:17:098162 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:508163 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c843192012-04-05 07:15:008164 TestCompletionCallback callback;
8165 int rv = trans->Start(&request, callback.callback(), log.bound());
8166 EXPECT_EQ(ERR_IO_PENDING, rv);
8167
8168 rv = callback.WaitForResult();
8169 EXPECT_EQ(OK, rv);
8170 const HttpResponseInfo* response = trans->GetResponseInfo();
8171
wezca1070932016-05-26 20:30:528172 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:008173 EXPECT_TRUE(response->headers->IsKeepAlive());
8174
8175 EXPECT_EQ(200, response->headers->response_code());
8176 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8177
8178 std::string response_data;
8179 rv = ReadTransaction(trans.get(), &response_data);
8180 EXPECT_EQ(OK, rv);
8181 EXPECT_EQ("hello!", response_data);
8182
8183 trans.reset();
8184 session->CloseAllConnections();
8185}
8186
tbansal8ef1d3e2016-02-03 04:05:428187// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
8188// resources.
8189TEST_P(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:158190 // Configure the proxy delegate to allow cross-origin SPDY pushes.
danakj1fd259a02016-04-16 03:17:098191 std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate());
tbansal28e68f82016-02-04 02:56:158192 proxy_delegate->set_trusted_spdy_proxy(
8193 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
8194
tbansal8ef1d3e2016-02-03 04:05:428195 HttpRequestInfo request;
8196
8197 request.method = "GET";
8198 request.url = GURL("http://www.example.org/");
8199
8200 // Configure against https proxy server "myproxy:70".
8201 session_deps_.proxy_service = ProxyService::CreateFixed("https://myproxy:70");
8202 BoundTestNetLog log;
8203 session_deps_.net_log = log.bound().net_log();
8204
8205 // Enable cross-origin push.
tbansal28e68f82016-02-04 02:56:158206 session_deps_.proxy_delegate.reset(proxy_delegate.release());
tbansal8ef1d3e2016-02-03 04:05:428207
danakj1fd259a02016-04-16 03:17:098208 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:428209
danakj1fd259a02016-04-16 03:17:098210 std::unique_ptr<SpdySerializedFrame> stream1_syn(
bnc38dcd392016-02-09 23:19:498211 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
tbansal8ef1d3e2016-02-03 04:05:428212
8213 MockWrite spdy_writes[] = {
8214 CreateMockWrite(*stream1_syn, 0, ASYNC),
8215 };
8216
danakj1fd259a02016-04-16 03:17:098217 std::unique_ptr<SpdySerializedFrame> stream1_reply(
tbansal8ef1d3e2016-02-03 04:05:428218 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
8219
danakj1fd259a02016-04-16 03:17:098220 std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
bnc38dcd392016-02-09 23:19:498221 nullptr, 0, 2, 1, "https://myproxy:70/foo.dat"));
8222
danakj1fd259a02016-04-16 03:17:098223 std::unique_ptr<SpdySerializedFrame> stream1_body(
tbansal8ef1d3e2016-02-03 04:05:428224 spdy_util_.ConstructSpdyBodyFrame(1, true));
8225
danakj1fd259a02016-04-16 03:17:098226 std::unique_ptr<SpdySerializedFrame> stream2_reply(
tbansal8ef1d3e2016-02-03 04:05:428227 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
8228
danakj1fd259a02016-04-16 03:17:098229 std::unique_ptr<SpdySerializedFrame> stream2_body(
tbansal8ef1d3e2016-02-03 04:05:428230 spdy_util_.ConstructSpdyBodyFrame(1, true));
8231
8232 MockRead spdy_reads[] = {
8233 CreateMockRead(*stream1_reply, 1, ASYNC),
8234 CreateMockRead(*stream2_syn, 2, ASYNC),
8235 CreateMockRead(*stream1_body, 3, ASYNC),
8236 CreateMockRead(*stream2_body, 4, ASYNC),
8237 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
8238 };
8239
8240 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
8241 arraysize(spdy_writes));
8242 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
8243 // Negotiate SPDY to the proxy
8244 SSLSocketDataProvider proxy(ASYNC, OK);
8245 proxy.SetNextProto(GetProtocol());
8246 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
8247
danakj1fd259a02016-04-16 03:17:098248 std::unique_ptr<HttpTransaction> trans(
tbansal8ef1d3e2016-02-03 04:05:428249 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
8250 TestCompletionCallback callback;
8251 int rv = trans->Start(&request, callback.callback(), log.bound());
8252 EXPECT_EQ(ERR_IO_PENDING, rv);
8253
8254 rv = callback.WaitForResult();
8255 EXPECT_EQ(OK, rv);
8256 const HttpResponseInfo* response = trans->GetResponseInfo();
8257
wezca1070932016-05-26 20:30:528258 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:428259 EXPECT_TRUE(response->headers->IsKeepAlive());
8260
8261 EXPECT_EQ(200, response->headers->response_code());
8262 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
8263
8264 std::string response_data;
8265 rv = ReadTransaction(trans.get(), &response_data);
8266 EXPECT_EQ(OK, rv);
8267 EXPECT_EQ("hello!", response_data);
8268
8269 trans.reset();
8270 session->CloseAllConnections();
8271}
8272
[email protected]2df19bb2010-08-25 20:13:468273// Test HTTPS connections to a site with a bad certificate, going through an
8274// HTTPS proxy
[email protected]23e482282013-06-14 16:08:028275TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
rdsmith82957ad2015-09-16 19:42:038276 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
[email protected]2df19bb2010-08-25 20:13:468277
8278 HttpRequestInfo request;
8279 request.method = "GET";
bncce36dca22015-04-21 22:11:238280 request.url = GURL("https://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:468281 request.load_flags = 0;
8282
8283 // Attempt to fetch the URL from a server with a bad cert
8284 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:178285 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8286 "Host: www.example.org:443\r\n"
8287 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468288 };
8289
8290 MockRead bad_cert_reads[] = {
8291 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068292 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:468293 };
8294
8295 // Attempt to fetch the URL with a good cert
8296 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178297 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8298 "Host: www.example.org:443\r\n"
8299 "Proxy-Connection: keep-alive\r\n\r\n"),
8300 MockWrite("GET / HTTP/1.1\r\n"
8301 "Host: www.example.org\r\n"
8302 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468303 };
8304
8305 MockRead good_cert_reads[] = {
8306 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8307 MockRead("HTTP/1.0 200 OK\r\n"),
8308 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8309 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068310 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468311 };
8312
8313 StaticSocketDataProvider ssl_bad_certificate(
8314 bad_cert_reads, arraysize(bad_cert_reads),
8315 bad_cert_writes, arraysize(bad_cert_writes));
8316 StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
8317 good_data_writes, arraysize(good_data_writes));
[email protected]8ddf8322012-02-23 18:08:068318 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8319 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:468320
8321 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:078322 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8323 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:468325
8326 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:078327 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8328 session_deps_.socket_factory->AddSocketDataProvider(&data);
8329 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:468330
[email protected]49639fa2011-12-20 23:22:418331 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468332
danakj1fd259a02016-04-16 03:17:098333 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8334 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418335 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2df19bb2010-08-25 20:13:468336
[email protected]49639fa2011-12-20 23:22:418337 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2df19bb2010-08-25 20:13:468338 EXPECT_EQ(ERR_IO_PENDING, rv);
8339
8340 rv = callback.WaitForResult();
8341 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
8342
[email protected]49639fa2011-12-20 23:22:418343 rv = trans->RestartIgnoringLastError(callback.callback());
[email protected]2df19bb2010-08-25 20:13:468344 EXPECT_EQ(ERR_IO_PENDING, rv);
8345
8346 rv = callback.WaitForResult();
8347 EXPECT_EQ(OK, rv);
8348
8349 const HttpResponseInfo* response = trans->GetResponseInfo();
8350
wezca1070932016-05-26 20:30:528351 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468352 EXPECT_EQ(100, response->headers->GetContentLength());
8353}
8354
[email protected]23e482282013-06-14 16:08:028355TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:428356 HttpRequestInfo request;
8357 request.method = "GET";
bncce36dca22015-04-21 22:11:238358 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438359 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8360 "Chromium Ultra Awesome X Edition");
[email protected]1c773ea12009-04-28 19:58:428361
danakj1fd259a02016-04-16 03:17:098362 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8363 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418364 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278365
[email protected]1c773ea12009-04-28 19:58:428366 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238367 MockWrite(
8368 "GET / HTTP/1.1\r\n"
8369 "Host: www.example.org\r\n"
8370 "Connection: keep-alive\r\n"
8371 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428372 };
8373
8374 // Lastly, the server responds with the actual content.
8375 MockRead data_reads[] = {
8376 MockRead("HTTP/1.0 200 OK\r\n"),
8377 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8378 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068379 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428380 };
8381
[email protected]31a2bfe2010-02-09 08:03:398382 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8383 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078384 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428385
[email protected]49639fa2011-12-20 23:22:418386 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428387
[email protected]49639fa2011-12-20 23:22:418388 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428389 EXPECT_EQ(ERR_IO_PENDING, rv);
8390
8391 rv = callback.WaitForResult();
8392 EXPECT_EQ(OK, rv);
8393}
8394
[email protected]23e482282013-06-14 16:08:028395TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:298396 HttpRequestInfo request;
8397 request.method = "GET";
bncce36dca22015-04-21 22:11:238398 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:298399 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
8400 "Chromium Ultra Awesome X Edition");
8401
rdsmith82957ad2015-09-16 19:42:038402 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
danakj1fd259a02016-04-16 03:17:098403 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8404 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418405 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278406
[email protected]da81f132010-08-18 23:39:298407 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178408 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8409 "Host: www.example.org:443\r\n"
8410 "Proxy-Connection: keep-alive\r\n"
8411 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:298412 };
8413 MockRead data_reads[] = {
8414 // Return an error, so the transaction stops here (this test isn't
8415 // interested in the rest).
8416 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
8417 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8418 MockRead("Proxy-Connection: close\r\n\r\n"),
8419 };
8420
8421 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8422 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078423 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:298424
[email protected]49639fa2011-12-20 23:22:418425 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:298426
[email protected]49639fa2011-12-20 23:22:418427 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]da81f132010-08-18 23:39:298428 EXPECT_EQ(ERR_IO_PENDING, rv);
8429
8430 rv = callback.WaitForResult();
8431 EXPECT_EQ(OK, rv);
8432}
8433
[email protected]23e482282013-06-14 16:08:028434TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:428435 HttpRequestInfo request;
8436 request.method = "GET";
bncce36dca22015-04-21 22:11:238437 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428438 request.load_flags = 0;
[email protected]c10450102011-06-27 09:06:168439 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
8440 "http://the.previous.site.com/");
[email protected]1c773ea12009-04-28 19:58:428441
danakj1fd259a02016-04-16 03:17:098442 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8443 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418444 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278445
[email protected]1c773ea12009-04-28 19:58:428446 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238447 MockWrite(
8448 "GET / HTTP/1.1\r\n"
8449 "Host: www.example.org\r\n"
8450 "Connection: keep-alive\r\n"
8451 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428452 };
8453
8454 // Lastly, the server responds with the actual content.
8455 MockRead data_reads[] = {
8456 MockRead("HTTP/1.0 200 OK\r\n"),
8457 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8458 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068459 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428460 };
8461
[email protected]31a2bfe2010-02-09 08:03:398462 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8463 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078464 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428465
[email protected]49639fa2011-12-20 23:22:418466 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428467
[email protected]49639fa2011-12-20 23:22:418468 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428469 EXPECT_EQ(ERR_IO_PENDING, rv);
8470
8471 rv = callback.WaitForResult();
8472 EXPECT_EQ(OK, rv);
8473}
8474
[email protected]23e482282013-06-14 16:08:028475TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428476 HttpRequestInfo request;
8477 request.method = "POST";
bncce36dca22015-04-21 22:11:238478 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428479
danakj1fd259a02016-04-16 03:17:098480 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8481 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418482 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278483
[email protected]1c773ea12009-04-28 19:58:428484 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238485 MockWrite(
8486 "POST / HTTP/1.1\r\n"
8487 "Host: www.example.org\r\n"
8488 "Connection: keep-alive\r\n"
8489 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428490 };
8491
8492 // Lastly, the server responds with the actual content.
8493 MockRead data_reads[] = {
8494 MockRead("HTTP/1.0 200 OK\r\n"),
8495 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8496 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068497 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428498 };
8499
[email protected]31a2bfe2010-02-09 08:03:398500 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8501 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078502 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428503
[email protected]49639fa2011-12-20 23:22:418504 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428505
[email protected]49639fa2011-12-20 23:22:418506 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428507 EXPECT_EQ(ERR_IO_PENDING, rv);
8508
8509 rv = callback.WaitForResult();
8510 EXPECT_EQ(OK, rv);
8511}
8512
[email protected]23e482282013-06-14 16:08:028513TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428514 HttpRequestInfo request;
8515 request.method = "PUT";
bncce36dca22015-04-21 22:11:238516 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428517
danakj1fd259a02016-04-16 03:17:098518 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8519 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418520 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278521
[email protected]1c773ea12009-04-28 19:58:428522 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238523 MockWrite(
8524 "PUT / HTTP/1.1\r\n"
8525 "Host: www.example.org\r\n"
8526 "Connection: keep-alive\r\n"
8527 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428528 };
8529
8530 // Lastly, the server responds with the actual content.
8531 MockRead data_reads[] = {
8532 MockRead("HTTP/1.0 200 OK\r\n"),
8533 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8534 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068535 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428536 };
8537
[email protected]31a2bfe2010-02-09 08:03:398538 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8539 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078540 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428541
[email protected]49639fa2011-12-20 23:22:418542 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428543
[email protected]49639fa2011-12-20 23:22:418544 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428545 EXPECT_EQ(ERR_IO_PENDING, rv);
8546
8547 rv = callback.WaitForResult();
8548 EXPECT_EQ(OK, rv);
8549}
8550
[email protected]23e482282013-06-14 16:08:028551TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:428552 HttpRequestInfo request;
8553 request.method = "HEAD";
bncce36dca22015-04-21 22:11:238554 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428555
danakj1fd259a02016-04-16 03:17:098556 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8557 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418558 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278559
[email protected]1c773ea12009-04-28 19:58:428560 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:138561 MockWrite("HEAD / HTTP/1.1\r\n"
8562 "Host: www.example.org\r\n"
8563 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428564 };
8565
8566 // Lastly, the server responds with the actual content.
8567 MockRead data_reads[] = {
8568 MockRead("HTTP/1.0 200 OK\r\n"),
8569 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8570 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068571 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428572 };
8573
[email protected]31a2bfe2010-02-09 08:03:398574 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8575 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078576 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428577
[email protected]49639fa2011-12-20 23:22:418578 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428579
[email protected]49639fa2011-12-20 23:22:418580 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428581 EXPECT_EQ(ERR_IO_PENDING, rv);
8582
8583 rv = callback.WaitForResult();
8584 EXPECT_EQ(OK, rv);
8585}
8586
[email protected]23e482282013-06-14 16:08:028587TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:428588 HttpRequestInfo request;
8589 request.method = "GET";
bncce36dca22015-04-21 22:11:238590 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428591 request.load_flags = LOAD_BYPASS_CACHE;
8592
danakj1fd259a02016-04-16 03:17:098593 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8594 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418595 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278596
[email protected]1c773ea12009-04-28 19:58:428597 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238598 MockWrite(
8599 "GET / HTTP/1.1\r\n"
8600 "Host: www.example.org\r\n"
8601 "Connection: keep-alive\r\n"
8602 "Pragma: no-cache\r\n"
8603 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428604 };
8605
8606 // Lastly, the server responds with the actual content.
8607 MockRead data_reads[] = {
8608 MockRead("HTTP/1.0 200 OK\r\n"),
8609 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8610 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068611 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428612 };
8613
[email protected]31a2bfe2010-02-09 08:03:398614 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8615 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078616 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428617
[email protected]49639fa2011-12-20 23:22:418618 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428619
[email protected]49639fa2011-12-20 23:22:418620 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428621 EXPECT_EQ(ERR_IO_PENDING, rv);
8622
8623 rv = callback.WaitForResult();
8624 EXPECT_EQ(OK, rv);
8625}
8626
[email protected]23e482282013-06-14 16:08:028627TEST_P(HttpNetworkTransactionTest,
[email protected]1c773ea12009-04-28 19:58:428628 BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:428629 HttpRequestInfo request;
8630 request.method = "GET";
bncce36dca22015-04-21 22:11:238631 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:428632 request.load_flags = LOAD_VALIDATE_CACHE;
8633
danakj1fd259a02016-04-16 03:17:098634 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8635 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418636 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278637
[email protected]1c773ea12009-04-28 19:58:428638 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238639 MockWrite(
8640 "GET / HTTP/1.1\r\n"
8641 "Host: www.example.org\r\n"
8642 "Connection: keep-alive\r\n"
8643 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428644 };
8645
8646 // Lastly, the server responds with the actual content.
8647 MockRead data_reads[] = {
8648 MockRead("HTTP/1.0 200 OK\r\n"),
8649 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8650 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068651 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428652 };
8653
[email protected]31a2bfe2010-02-09 08:03:398654 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8655 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078656 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428657
[email protected]49639fa2011-12-20 23:22:418658 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428659
[email protected]49639fa2011-12-20 23:22:418660 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428661 EXPECT_EQ(ERR_IO_PENDING, rv);
8662
8663 rv = callback.WaitForResult();
8664 EXPECT_EQ(OK, rv);
8665}
8666
[email protected]23e482282013-06-14 16:08:028667TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:428668 HttpRequestInfo request;
8669 request.method = "GET";
bncce36dca22015-04-21 22:11:238670 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438671 request.extra_headers.SetHeader("FooHeader", "Bar");
[email protected]1c773ea12009-04-28 19:58:428672
danakj1fd259a02016-04-16 03:17:098673 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8674 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418675 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278676
[email protected]1c773ea12009-04-28 19:58:428677 MockWrite data_writes[] = {
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 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:428683 };
8684
8685 // Lastly, the server responds with the actual content.
8686 MockRead data_reads[] = {
8687 MockRead("HTTP/1.0 200 OK\r\n"),
8688 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8689 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068690 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:428691 };
8692
[email protected]31a2bfe2010-02-09 08:03:398693 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8694 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078695 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:428696
[email protected]49639fa2011-12-20 23:22:418697 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:428698
[email protected]49639fa2011-12-20 23:22:418699 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]1c773ea12009-04-28 19:58:428700 EXPECT_EQ(ERR_IO_PENDING, rv);
8701
8702 rv = callback.WaitForResult();
8703 EXPECT_EQ(OK, rv);
8704}
8705
[email protected]23e482282013-06-14 16:08:028706TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:478707 HttpRequestInfo request;
8708 request.method = "GET";
bncce36dca22015-04-21 22:11:238709 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:438710 request.extra_headers.SetHeader("referer", "www.foo.com");
8711 request.extra_headers.SetHeader("hEllo", "Kitty");
8712 request.extra_headers.SetHeader("FoO", "bar");
[email protected]270c6412010-03-29 22:02:478713
danakj1fd259a02016-04-16 03:17:098714 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8715 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418716 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:278717
[email protected]270c6412010-03-29 22:02:478718 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238719 MockWrite(
8720 "GET / HTTP/1.1\r\n"
8721 "Host: www.example.org\r\n"
8722 "Connection: keep-alive\r\n"
8723 "referer: www.foo.com\r\n"
8724 "hEllo: Kitty\r\n"
8725 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:478726 };
8727
8728 // Lastly, the server responds with the actual content.
8729 MockRead data_reads[] = {
8730 MockRead("HTTP/1.0 200 OK\r\n"),
8731 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8732 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068733 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:478734 };
8735
8736 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8737 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078738 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:478739
[email protected]49639fa2011-12-20 23:22:418740 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:478741
[email protected]49639fa2011-12-20 23:22:418742 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]270c6412010-03-29 22:02:478743 EXPECT_EQ(ERR_IO_PENDING, rv);
8744
8745 rv = callback.WaitForResult();
8746 EXPECT_EQ(OK, rv);
8747}
8748
[email protected]23e482282013-06-14 16:08:028749TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278750 HttpRequestInfo request;
8751 request.method = "GET";
bncce36dca22015-04-21 22:11:238752 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278753 request.load_flags = 0;
8754
rdsmith82957ad2015-09-16 19:42:038755 session_deps_.proxy_service =
8756 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518757 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078758 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028759
danakj1fd259a02016-04-16 03:17:098760 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8761 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418762 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:028763
[email protected]3cd17242009-06-23 02:59:028764 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8765 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8766
8767 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238768 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8769 MockWrite(
8770 "GET / HTTP/1.1\r\n"
8771 "Host: www.example.org\r\n"
8772 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028773
8774 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:068775 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:028776 MockRead("HTTP/1.0 200 OK\r\n"),
8777 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8778 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068779 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:028780 };
8781
[email protected]31a2bfe2010-02-09 08:03:398782 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8783 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078784 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:028785
[email protected]49639fa2011-12-20 23:22:418786 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:028787
[email protected]49639fa2011-12-20 23:22:418788 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:028789 EXPECT_EQ(ERR_IO_PENDING, rv);
8790
8791 rv = callback.WaitForResult();
8792 EXPECT_EQ(OK, rv);
8793
8794 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528795 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:028796
[email protected]029c83b62013-01-24 05:28:208797 LoadTimingInfo load_timing_info;
8798 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8799 TestLoadTimingNotReusedWithPac(load_timing_info,
8800 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8801
[email protected]3cd17242009-06-23 02:59:028802 std::string response_text;
8803 rv = ReadTransaction(trans.get(), &response_text);
8804 EXPECT_EQ(OK, rv);
8805 EXPECT_EQ("Payload", response_text);
8806}
8807
[email protected]23e482282013-06-14 16:08:028808TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278809 HttpRequestInfo request;
8810 request.method = "GET";
bncce36dca22015-04-21 22:11:238811 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278812 request.load_flags = 0;
8813
rdsmith82957ad2015-09-16 19:42:038814 session_deps_.proxy_service =
8815 ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518816 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078817 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:028818
danakj1fd259a02016-04-16 03:17:098819 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8820 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418821 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3cd17242009-06-23 02:59:028822
[email protected]3cd17242009-06-23 02:59:028823 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
8824 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8825
8826 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238827 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
8828 arraysize(write_buffer)),
8829 MockWrite(
8830 "GET / HTTP/1.1\r\n"
8831 "Host: www.example.org\r\n"
8832 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:028833
8834 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018835 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
8836 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:358837 MockRead("HTTP/1.0 200 OK\r\n"),
8838 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8839 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068840 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358841 };
8842
[email protected]31a2bfe2010-02-09 08:03:398843 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8844 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078845 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358846
[email protected]8ddf8322012-02-23 18:08:068847 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078848 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:358849
[email protected]49639fa2011-12-20 23:22:418850 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358851
[email protected]49639fa2011-12-20 23:22:418852 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:358853 EXPECT_EQ(ERR_IO_PENDING, rv);
8854
8855 rv = callback.WaitForResult();
8856 EXPECT_EQ(OK, rv);
8857
[email protected]029c83b62013-01-24 05:28:208858 LoadTimingInfo load_timing_info;
8859 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8860 TestLoadTimingNotReusedWithPac(load_timing_info,
8861 CONNECT_TIMING_HAS_SSL_TIMES);
8862
[email protected]e0c27be2009-07-15 13:09:358863 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528864 ASSERT_TRUE(response);
[email protected]e0c27be2009-07-15 13:09:358865
8866 std::string response_text;
8867 rv = ReadTransaction(trans.get(), &response_text);
8868 EXPECT_EQ(OK, rv);
8869 EXPECT_EQ("Payload", response_text);
8870}
8871
[email protected]23e482282013-06-14 16:08:028872TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:208873 HttpRequestInfo request;
8874 request.method = "GET";
bncce36dca22015-04-21 22:11:238875 request.url = GURL("http://www.example.org/");
[email protected]029c83b62013-01-24 05:28:208876 request.load_flags = 0;
8877
rdsmith82957ad2015-09-16 19:42:038878 session_deps_.proxy_service =
8879 ProxyService::CreateFixed("socks4://myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518880 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078881 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:208882
danakj1fd259a02016-04-16 03:17:098883 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8884 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418885 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]029c83b62013-01-24 05:28:208886
8887 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
8888 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
8889
8890 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238891 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
8892 MockWrite(
8893 "GET / HTTP/1.1\r\n"
8894 "Host: www.example.org\r\n"
8895 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:208896
8897 MockRead data_reads[] = {
8898 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
8899 MockRead("HTTP/1.0 200 OK\r\n"),
8900 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8901 MockRead("Payload"),
8902 MockRead(SYNCHRONOUS, OK)
8903 };
8904
8905 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8906 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078907 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:208908
8909 TestCompletionCallback callback;
8910
8911 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
8912 EXPECT_EQ(ERR_IO_PENDING, rv);
8913
8914 rv = callback.WaitForResult();
8915 EXPECT_EQ(OK, rv);
8916
8917 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528918 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:208919
8920 LoadTimingInfo load_timing_info;
8921 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8922 TestLoadTimingNotReused(load_timing_info,
8923 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8924
8925 std::string response_text;
8926 rv = ReadTransaction(trans.get(), &response_text);
8927 EXPECT_EQ(OK, rv);
8928 EXPECT_EQ("Payload", response_text);
8929}
8930
[email protected]23e482282013-06-14 16:08:028931TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:278932 HttpRequestInfo request;
8933 request.method = "GET";
bncce36dca22015-04-21 22:11:238934 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:278935 request.load_flags = 0;
8936
rdsmith82957ad2015-09-16 19:42:038937 session_deps_.proxy_service =
8938 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:518939 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078940 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:358941
danakj1fd259a02016-04-16 03:17:098942 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8943 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:418944 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:358945
[email protected]e0c27be2009-07-15 13:09:358946 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
8947 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:378948 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:238949 0x05, // Version
8950 0x01, // Command (CONNECT)
8951 0x00, // Reserved.
8952 0x03, // Address type (DOMAINNAME).
8953 0x0F, // Length of domain (15)
8954 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
8955 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:378956 };
[email protected]e0c27be2009-07-15 13:09:358957 const char kSOCKS5OkResponse[] =
8958 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
8959
8960 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238961 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
8962 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
8963 MockWrite(
8964 "GET / HTTP/1.1\r\n"
8965 "Host: www.example.org\r\n"
8966 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:358967
8968 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:018969 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
8970 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:358971 MockRead("HTTP/1.0 200 OK\r\n"),
8972 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
8973 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:068974 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:358975 };
8976
[email protected]31a2bfe2010-02-09 08:03:398977 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
8978 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:078979 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:358980
[email protected]49639fa2011-12-20 23:22:418981 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:358982
[email protected]49639fa2011-12-20 23:22:418983 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]e0c27be2009-07-15 13:09:358984 EXPECT_EQ(ERR_IO_PENDING, rv);
8985
8986 rv = callback.WaitForResult();
8987 EXPECT_EQ(OK, rv);
8988
8989 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528990 ASSERT_TRUE(response);
[email protected]e0c27be2009-07-15 13:09:358991
[email protected]029c83b62013-01-24 05:28:208992 LoadTimingInfo load_timing_info;
8993 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
8994 TestLoadTimingNotReusedWithPac(load_timing_info,
8995 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
8996
[email protected]e0c27be2009-07-15 13:09:358997 std::string response_text;
8998 rv = ReadTransaction(trans.get(), &response_text);
8999 EXPECT_EQ(OK, rv);
9000 EXPECT_EQ("Payload", response_text);
9001}
9002
[email protected]23e482282013-06-14 16:08:029003TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279004 HttpRequestInfo request;
9005 request.method = "GET";
bncce36dca22015-04-21 22:11:239006 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279007 request.load_flags = 0;
9008
rdsmith82957ad2015-09-16 19:42:039009 session_deps_.proxy_service =
9010 ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080");
vishal.b62985ca92015-04-17 08:45:519011 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079012 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:359013
danakj1fd259a02016-04-16 03:17:099014 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9015 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419016 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]e0c27be2009-07-15 13:09:359017
[email protected]e0c27be2009-07-15 13:09:359018 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
9019 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:379020 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:239021 0x05, // Version
9022 0x01, // Command (CONNECT)
9023 0x00, // Reserved.
9024 0x03, // Address type (DOMAINNAME).
9025 0x0F, // Length of domain (15)
9026 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
9027 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:379028 };
9029
[email protected]e0c27be2009-07-15 13:09:359030 const char kSOCKS5OkResponse[] =
9031 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
9032
9033 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239034 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
9035 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
9036 arraysize(kSOCKS5OkRequest)),
9037 MockWrite(
9038 "GET / HTTP/1.1\r\n"
9039 "Host: www.example.org\r\n"
9040 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:359041
9042 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019043 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
9044 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:029045 MockRead("HTTP/1.0 200 OK\r\n"),
9046 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9047 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069048 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029049 };
9050
[email protected]31a2bfe2010-02-09 08:03:399051 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
9052 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:079053 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029054
[email protected]8ddf8322012-02-23 18:08:069055 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079056 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:029057
[email protected]49639fa2011-12-20 23:22:419058 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029059
[email protected]49639fa2011-12-20 23:22:419060 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3cd17242009-06-23 02:59:029061 EXPECT_EQ(ERR_IO_PENDING, rv);
9062
9063 rv = callback.WaitForResult();
9064 EXPECT_EQ(OK, rv);
9065
9066 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529067 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029068
[email protected]029c83b62013-01-24 05:28:209069 LoadTimingInfo load_timing_info;
9070 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9071 TestLoadTimingNotReusedWithPac(load_timing_info,
9072 CONNECT_TIMING_HAS_SSL_TIMES);
9073
[email protected]3cd17242009-06-23 02:59:029074 std::string response_text;
9075 rv = ReadTransaction(trans.get(), &response_text);
9076 EXPECT_EQ(OK, rv);
9077 EXPECT_EQ("Payload", response_text);
9078}
9079
[email protected]448d4ca52012-03-04 04:12:239080namespace {
9081
[email protected]04e5be32009-06-26 20:00:319082// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:069083
9084struct GroupNameTest {
9085 std::string proxy_server;
9086 std::string url;
9087 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:189088 bool ssl;
[email protected]2d731a32010-04-29 01:04:069089};
9090
danakj1fd259a02016-04-16 03:17:099091std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]8a0fc822013-06-27 20:52:439092 NextProto next_proto,
[email protected]bb88e1d32013-05-03 23:11:079093 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:099094 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:069095
bnc525e175a2016-06-20 12:36:409096 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:539097 session->http_server_properties();
bnccacc0992015-03-20 20:22:229098 AlternativeService alternative_service(
bncaa60ff402016-06-22 19:12:429099 AlternateProtocolFromNextProto(next_proto), "", 444);
bnc7dc7e1b42015-07-28 14:43:129100 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:229101 http_server_properties->SetAlternativeService(
bncaa60ff402016-06-22 19:12:429102 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:469103 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:069104
9105 return session;
9106}
9107
mmenkee65e7af2015-10-13 17:16:429108int GroupNameTransactionHelper(const std::string& url,
9109 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:069110 HttpRequestInfo request;
9111 request.method = "GET";
9112 request.url = GURL(url);
9113 request.load_flags = 0;
9114
danakj1fd259a02016-04-16 03:17:099115 std::unique_ptr<HttpTransaction> trans(
mmenkee65e7af2015-10-13 17:16:429116 new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
[email protected]cb9bf6ca2011-01-28 13:15:279117
[email protected]49639fa2011-12-20 23:22:419118 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:069119
9120 // We do not complete this request, the dtor will clean the transaction up.
[email protected]49639fa2011-12-20 23:22:419121 return trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d731a32010-04-29 01:04:069122}
9123
[email protected]448d4ca52012-03-04 04:12:239124} // namespace
9125
[email protected]23e482282013-06-14 16:08:029126TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:069127 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239128 {
9129 "", // unused
9130 "http://www.example.org/direct",
9131 "www.example.org:80",
9132 false,
9133 },
9134 {
9135 "", // unused
9136 "http://[2001:1418:13:1::25]/direct",
9137 "[2001:1418:13:1::25]:80",
9138 false,
9139 },
[email protected]04e5be32009-06-26 20:00:319140
bncce36dca22015-04-21 22:11:239141 // SSL Tests
9142 {
9143 "", // unused
9144 "https://www.example.org/direct_ssl",
9145 "ssl/www.example.org:443",
9146 true,
9147 },
9148 {
9149 "", // unused
9150 "https://[2001:1418:13:1::25]/direct",
9151 "ssl/[2001:1418:13:1::25]:443",
9152 true,
9153 },
9154 {
9155 "", // unused
bncaa60ff402016-06-22 19:12:429156 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239157 "ssl/host.with.alternate:443",
9158 true,
9159 },
[email protected]2d731a32010-04-29 01:04:069160 };
[email protected]2ff8b312010-04-26 22:20:549161
bncf33fb31b2016-01-29 15:22:269162 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]2d731a32010-04-29 01:04:069163
viettrungluue4a8b882014-10-16 06:17:389164 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039165 session_deps_.proxy_service =
9166 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099167 std::unique_ptr<HttpNetworkSession> session(
rdsmithebb50aa2015-11-12 03:44:389168 SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:069169
mmenkee65e7af2015-10-13 17:16:429170 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:289171 CaptureGroupNameTransportSocketPool* transport_conn_pool =
9172 new CaptureGroupNameTransportSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139173 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349174 new CaptureGroupNameSSLSocketPool(NULL, NULL);
danakj1fd259a02016-04-16 03:17:099175 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449176 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029177 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
9178 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489179 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069180
9181 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429182 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189183 if (tests[i].ssl)
9184 EXPECT_EQ(tests[i].expected_group_name,
9185 ssl_conn_pool->last_group_name_received());
9186 else
9187 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:289188 transport_conn_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069189 }
[email protected]2d731a32010-04-29 01:04:069190}
9191
[email protected]23e482282013-06-14 16:08:029192TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:069193 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239194 {
9195 "http_proxy",
9196 "http://www.example.org/http_proxy_normal",
9197 "www.example.org:80",
9198 false,
9199 },
[email protected]2d731a32010-04-29 01:04:069200
bncce36dca22015-04-21 22:11:239201 // SSL Tests
9202 {
9203 "http_proxy",
9204 "https://www.example.org/http_connect_ssl",
9205 "ssl/www.example.org:443",
9206 true,
9207 },
[email protected]af3490e2010-10-16 21:02:299208
bncce36dca22015-04-21 22:11:239209 {
9210 "http_proxy",
bncaa60ff402016-06-22 19:12:429211 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239212 "ssl/host.with.alternate:443",
9213 true,
9214 },
[email protected]45499252013-01-23 17:12:569215
bncce36dca22015-04-21 22:11:239216 {
9217 "http_proxy",
9218 "ftp://ftp.google.com/http_proxy_normal",
9219 "ftp/ftp.google.com:21",
9220 false,
9221 },
[email protected]2d731a32010-04-29 01:04:069222 };
9223
bncf33fb31b2016-01-29 15:22:269224 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]2d731a32010-04-29 01:04:069225
viettrungluue4a8b882014-10-16 06:17:389226 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039227 session_deps_.proxy_service =
9228 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099229 std::unique_ptr<HttpNetworkSession> session(
rdsmithebb50aa2015-11-12 03:44:389230 SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
[email protected]2d731a32010-04-29 01:04:069231
mmenkee65e7af2015-10-13 17:16:429232 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:069233
[email protected]e60e47a2010-07-14 03:37:189234 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:139235 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:349236 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139237 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349238 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:029239
danakj1fd259a02016-04-16 03:17:099240 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449241 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029242 mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
9243 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489244 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:069245
9246 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429247 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189248 if (tests[i].ssl)
9249 EXPECT_EQ(tests[i].expected_group_name,
9250 ssl_conn_pool->last_group_name_received());
9251 else
9252 EXPECT_EQ(tests[i].expected_group_name,
9253 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:069254 }
[email protected]2d731a32010-04-29 01:04:069255}
9256
[email protected]23e482282013-06-14 16:08:029257TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:069258 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:239259 {
9260 "socks4://socks_proxy:1080",
9261 "http://www.example.org/socks4_direct",
9262 "socks4/www.example.org:80",
9263 false,
9264 },
9265 {
9266 "socks5://socks_proxy:1080",
9267 "http://www.example.org/socks5_direct",
9268 "socks5/www.example.org:80",
9269 false,
9270 },
[email protected]2d731a32010-04-29 01:04:069271
bncce36dca22015-04-21 22:11:239272 // SSL Tests
9273 {
9274 "socks4://socks_proxy:1080",
9275 "https://www.example.org/socks4_ssl",
9276 "socks4/ssl/www.example.org:443",
9277 true,
9278 },
9279 {
9280 "socks5://socks_proxy:1080",
9281 "https://www.example.org/socks5_ssl",
9282 "socks5/ssl/www.example.org:443",
9283 true,
9284 },
[email protected]af3490e2010-10-16 21:02:299285
bncce36dca22015-04-21 22:11:239286 {
9287 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:429288 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:239289 "socks4/ssl/host.with.alternate:443",
9290 true,
9291 },
[email protected]04e5be32009-06-26 20:00:319292 };
9293
bncf33fb31b2016-01-29 15:22:269294 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]2ff8b312010-04-26 22:20:549295
viettrungluue4a8b882014-10-16 06:17:389296 for (size_t i = 0; i < arraysize(tests); ++i) {
rdsmith82957ad2015-09-16 19:42:039297 session_deps_.proxy_service =
9298 ProxyService::CreateFixed(tests[i].proxy_server);
danakj1fd259a02016-04-16 03:17:099299 std::unique_ptr<HttpNetworkSession> session(
rdsmithebb50aa2015-11-12 03:44:389300 SetupSessionForGroupNameTests(GetProtocol(), &session_deps_));
[email protected]8b114dd72011-03-25 05:33:029301
mmenkee65e7af2015-10-13 17:16:429302 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:319303
[email protected]e60e47a2010-07-14 03:37:189304 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:139305 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349306 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:139307 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:349308 new CaptureGroupNameSSLSocketPool(NULL, NULL);
[email protected]a42dbd142011-11-17 16:42:029309
danakj1fd259a02016-04-16 03:17:099310 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:449311 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:029312 mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
9313 mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:489314 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:319315
danakj1fd259a02016-04-16 03:17:099316 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509317 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]04e5be32009-06-26 20:00:319318
[email protected]2d731a32010-04-29 01:04:069319 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:429320 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:189321 if (tests[i].ssl)
9322 EXPECT_EQ(tests[i].expected_group_name,
9323 ssl_conn_pool->last_group_name_received());
9324 else
9325 EXPECT_EQ(tests[i].expected_group_name,
9326 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:319327 }
9328}
9329
[email protected]23e482282013-06-14 16:08:029330TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:279331 HttpRequestInfo request;
9332 request.method = "GET";
bncce36dca22015-04-21 22:11:239333 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279334
rdsmith82957ad2015-09-16 19:42:039335 session_deps_.proxy_service =
9336 ProxyService::CreateFixed("myproxy:70;foobar:80");
[email protected]b59ff372009-07-15 22:04:329337
[email protected]69719062010-01-05 20:09:219338 // This simulates failure resolving all hostnames; that means we will fail
9339 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:079340 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:329341
danakj1fd259a02016-04-16 03:17:099342 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9343 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419344 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]9172a982009-06-06 00:30:259345
[email protected]49639fa2011-12-20 23:22:419346 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:259347
[email protected]49639fa2011-12-20 23:22:419348 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9172a982009-06-06 00:30:259349 EXPECT_EQ(ERR_IO_PENDING, rv);
9350
[email protected]9172a982009-06-06 00:30:259351 rv = callback.WaitForResult();
[email protected]f7fccee2010-09-16 20:53:019352 EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]9172a982009-06-06 00:30:259353}
9354
[email protected]685af592010-05-11 19:31:249355// Base test to make sure that when the load flags for a request specify to
9356// bypass the cache, the DNS cache is not used.
[email protected]23e482282013-06-14 16:08:029357void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
[email protected]bb88e1d32013-05-03 23:11:079358 int load_flags) {
[email protected]cb9bf6ca2011-01-28 13:15:279359 // Issue a request, asking to bypass the cache(s).
9360 HttpRequestInfo request;
9361 request.method = "GET";
9362 request.load_flags = load_flags;
bncce36dca22015-04-21 22:11:239363 request.url = GURL("http://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:279364
[email protected]a2c2fb92009-07-18 07:31:049365 // Select a host resolver that does caching.
[email protected]bb88e1d32013-05-03 23:11:079366 session_deps_.host_resolver.reset(new MockCachingHostResolver);
[email protected]b59ff372009-07-15 22:04:329367
danakj1fd259a02016-04-16 03:17:099368 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9369 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419370 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]3b9cca42009-06-16 01:08:289371
bncce36dca22015-04-21 22:11:239372 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289373 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:299374 TestCompletionCallback callback;
[email protected]bb88e1d32013-05-03 23:11:079375 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239376 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
9377 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:479378 EXPECT_EQ(ERR_IO_PENDING, rv);
9379 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289380 EXPECT_EQ(OK, rv);
9381
9382 // Verify that it was added to host cache, by doing a subsequent async lookup
9383 // and confirming it completes synchronously.
[email protected]bb88e1d32013-05-03 23:11:079384 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:239385 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
9386 DEFAULT_PRIORITY, &addrlist, callback.callback(), NULL, BoundNetLog());
[email protected]b59ff372009-07-15 22:04:329387 ASSERT_EQ(OK, rv);
[email protected]3b9cca42009-06-16 01:08:289388
bncce36dca22015-04-21 22:11:239389 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:289390 // we can tell if the next lookup hit the cache, or the "network".
9391 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:239392 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:289393
9394 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
9395 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:069396 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
[email protected]31a2bfe2010-02-09 08:03:399397 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079398 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:289399
[email protected]3b9cca42009-06-16 01:08:289400 // Run the request.
[email protected]49639fa2011-12-20 23:22:419401 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]3b9cca42009-06-16 01:08:289402 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:419403 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:289404
9405 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:239406 // "www.example.org".
[email protected]3b9cca42009-06-16 01:08:289407 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
9408}
9409
[email protected]685af592010-05-11 19:31:249410// There are multiple load flags that should trigger the host cache bypass.
9411// Test each in isolation:
[email protected]23e482282013-06-14 16:08:029412TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
[email protected]685af592010-05-11 19:31:249413 BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
9414}
9415
[email protected]23e482282013-06-14 16:08:029416TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
[email protected]685af592010-05-11 19:31:249417 BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
9418}
9419
[email protected]23e482282013-06-14 16:08:029420TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
[email protected]685af592010-05-11 19:31:249421 BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
9422}
9423
[email protected]0877e3d2009-10-17 22:29:579424// Make sure we can handle an error when writing the request.
[email protected]23e482282013-06-14 16:08:029425TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:579426 HttpRequestInfo request;
9427 request.method = "GET";
9428 request.url = GURL("http://www.foo.com/");
9429 request.load_flags = 0;
9430
9431 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:069432 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579433 };
[email protected]31a2bfe2010-02-09 08:03:399434 StaticSocketDataProvider data(NULL, 0,
9435 write_failure, arraysize(write_failure));
[email protected]bb88e1d32013-05-03 23:11:079436 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099437 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579438
[email protected]49639fa2011-12-20 23:22:419439 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579440
danakj1fd259a02016-04-16 03:17:099441 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419442 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:579443
[email protected]49639fa2011-12-20 23:22:419444 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579445 EXPECT_EQ(ERR_IO_PENDING, rv);
9446
9447 rv = callback.WaitForResult();
9448 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
ttuttled9dbc652015-09-29 20:00:599449
9450 IPEndPoint endpoint;
9451 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
9452 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579453}
9454
zmo9528c9f42015-08-04 22:12:089455// Check that a connection closed after the start of the headers finishes ok.
9456TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:579457 HttpRequestInfo request;
9458 request.method = "GET";
9459 request.url = GURL("http://www.foo.com/");
9460 request.load_flags = 0;
9461
9462 MockRead data_reads[] = {
9463 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:069464 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579465 };
9466
[email protected]31a2bfe2010-02-09 08:03:399467 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079468 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:099469 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579470
[email protected]49639fa2011-12-20 23:22:419471 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579472
danakj1fd259a02016-04-16 03:17:099473 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419474 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:579475
[email protected]49639fa2011-12-20 23:22:419476 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579477 EXPECT_EQ(ERR_IO_PENDING, rv);
9478
9479 rv = callback.WaitForResult();
zmo9528c9f42015-08-04 22:12:089480 EXPECT_EQ(OK, rv);
9481
9482 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529483 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:089484
wezca1070932016-05-26 20:30:529485 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:089486 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9487
9488 std::string response_data;
9489 rv = ReadTransaction(trans.get(), &response_data);
9490 EXPECT_EQ(OK, rv);
9491 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:599492
9493 IPEndPoint endpoint;
9494 EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint));
9495 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:579496}
9497
9498// Make sure that a dropped connection while draining the body for auth
9499// restart does the right thing.
[email protected]23e482282013-06-14 16:08:029500TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:579501 HttpRequestInfo request;
9502 request.method = "GET";
bncce36dca22015-04-21 22:11:239503 request.url = GURL("http://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579504 request.load_flags = 0;
9505
9506 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239507 MockWrite(
9508 "GET / HTTP/1.1\r\n"
9509 "Host: www.example.org\r\n"
9510 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579511 };
9512
9513 MockRead data_reads1[] = {
9514 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
9515 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9516 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9517 MockRead("Content-Length: 14\r\n\r\n"),
9518 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:069519 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:579520 };
9521
[email protected]31a2bfe2010-02-09 08:03:399522 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9523 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:079524 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:579525
9526 // After calling trans->RestartWithAuth(), this is the request we should
9527 // be issuing -- the final header line contains the credentials.
9528 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239529 MockWrite(
9530 "GET / HTTP/1.1\r\n"
9531 "Host: www.example.org\r\n"
9532 "Connection: keep-alive\r\n"
9533 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:579534 };
9535
9536 // Lastly, the server responds with the actual content.
9537 MockRead data_reads2[] = {
9538 MockRead("HTTP/1.1 200 OK\r\n"),
9539 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9540 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069541 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:579542 };
9543
[email protected]31a2bfe2010-02-09 08:03:399544 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9545 data_writes2, arraysize(data_writes2));
[email protected]bb88e1d32013-05-03 23:11:079546 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:099547 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:579548
[email protected]49639fa2011-12-20 23:22:419549 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:579550
danakj1fd259a02016-04-16 03:17:099551 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:509552 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509553
[email protected]49639fa2011-12-20 23:22:419554 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579555 EXPECT_EQ(ERR_IO_PENDING, rv);
9556
9557 rv = callback1.WaitForResult();
9558 EXPECT_EQ(OK, rv);
9559
9560 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529561 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049562 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:579563
[email protected]49639fa2011-12-20 23:22:419564 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:579565
[email protected]49639fa2011-12-20 23:22:419566 rv = trans->RestartWithAuth(
9567 AuthCredentials(kFoo, kBar), callback2.callback());
[email protected]0877e3d2009-10-17 22:29:579568 EXPECT_EQ(ERR_IO_PENDING, rv);
9569
9570 rv = callback2.WaitForResult();
9571 EXPECT_EQ(OK, rv);
9572
9573 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529574 ASSERT_TRUE(response);
9575 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:579576 EXPECT_EQ(100, response->headers->GetContentLength());
9577}
9578
9579// Test HTTPS connections going through a proxy that sends extra data.
[email protected]23e482282013-06-14 16:08:029580TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
rdsmith82957ad2015-09-16 19:42:039581 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
[email protected]0877e3d2009-10-17 22:29:579582
9583 HttpRequestInfo request;
9584 request.method = "GET";
bncce36dca22015-04-21 22:11:239585 request.url = GURL("https://www.example.org/");
[email protected]0877e3d2009-10-17 22:29:579586 request.load_flags = 0;
9587
9588 MockRead proxy_reads[] = {
9589 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:069590 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:579591 };
9592
[email protected]31a2bfe2010-02-09 08:03:399593 StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
[email protected]8ddf8322012-02-23 18:08:069594 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:579595
[email protected]bb88e1d32013-05-03 23:11:079596 session_deps_.socket_factory->AddSocketDataProvider(&data);
9597 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:579598
[email protected]49639fa2011-12-20 23:22:419599 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:579600
[email protected]bb88e1d32013-05-03 23:11:079601 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:579602
danakj1fd259a02016-04-16 03:17:099603 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9604 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419605 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0877e3d2009-10-17 22:29:579606
[email protected]49639fa2011-12-20 23:22:419607 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]0877e3d2009-10-17 22:29:579608 EXPECT_EQ(ERR_IO_PENDING, rv);
9609
9610 rv = callback.WaitForResult();
9611 EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
9612}
9613
[email protected]23e482282013-06-14 16:08:029614TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:469615 HttpRequestInfo request;
9616 request.method = "GET";
bncce36dca22015-04-21 22:11:239617 request.url = GURL("http://www.example.org/");
[email protected]9492e4a2010-02-24 00:58:469618 request.load_flags = 0;
9619
danakj1fd259a02016-04-16 03:17:099620 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9621 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419622 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:279623
[email protected]e22e1362009-11-23 21:31:129624 MockRead data_reads[] = {
9625 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069626 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:129627 };
[email protected]9492e4a2010-02-24 00:58:469628
9629 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079630 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:469631
[email protected]49639fa2011-12-20 23:22:419632 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:469633
[email protected]49639fa2011-12-20 23:22:419634 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]9492e4a2010-02-24 00:58:469635 EXPECT_EQ(ERR_IO_PENDING, rv);
9636
9637 EXPECT_EQ(OK, callback.WaitForResult());
9638
9639 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529640 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:469641
wezca1070932016-05-26 20:30:529642 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:469643 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
9644
9645 std::string response_data;
9646 rv = ReadTransaction(trans.get(), &response_data);
[email protected]5543cbb2012-04-20 16:35:239647 EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
[email protected]e22e1362009-11-23 21:31:129648}
9649
[email protected]23e482282013-06-14 16:08:029650TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:159651 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:529652 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:149653 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:219654 UploadFileElementReader::ScopedOverridingContentLengthForTests
9655 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:339656
danakj1fd259a02016-04-16 03:17:099657 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9658 element_readers.push_back(base::WrapUnique(new UploadFileElementReader(
avibf0746c2015-12-09 19:53:149659 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
9660 std::numeric_limits<uint64_t>::max(), base::Time())));
olli.raula6df48b2a2015-11-26 07:40:229661 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279662
9663 HttpRequestInfo request;
9664 request.method = "POST";
bncce36dca22015-04-21 22:11:239665 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279666 request.upload_data_stream = &upload_data_stream;
9667 request.load_flags = 0;
9668
danakj1fd259a02016-04-16 03:17:099669 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9670 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419671 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]95d88ffe2010-02-04 21:25:339672
9673 MockRead data_reads[] = {
9674 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
9675 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:069676 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:339677 };
[email protected]31a2bfe2010-02-09 08:03:399678 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079679 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:339680
[email protected]49639fa2011-12-20 23:22:419681 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:339682
[email protected]49639fa2011-12-20 23:22:419683 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]95d88ffe2010-02-04 21:25:339684 EXPECT_EQ(ERR_IO_PENDING, rv);
9685
9686 rv = callback.WaitForResult();
maksim.sisove869bf52016-06-23 17:11:529687 EXPECT_EQ(ERR_UPLOAD_FILE_CHANGED, rv);
[email protected]95d88ffe2010-02-04 21:25:339688
9689 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529690 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:339691
maksim.sisove869bf52016-06-23 17:11:529692 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:339693
[email protected]dd3aa792013-07-16 19:10:239694 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:339695}
9696
[email protected]23e482282013-06-14 16:08:029697TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:159698 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:529699 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:369700 std::string temp_file_content("Unreadable file.");
[email protected]e5c2a22e2014-03-06 20:42:309701 ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
[email protected]6624b4622010-03-29 19:58:369702 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:119703 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:369704
danakj1fd259a02016-04-16 03:17:099705 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9706 element_readers.push_back(base::WrapUnique(new UploadFileElementReader(
avibf0746c2015-12-09 19:53:149707 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
9708 std::numeric_limits<uint64_t>::max(), base::Time())));
olli.raula6df48b2a2015-11-26 07:40:229709 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:279710
9711 HttpRequestInfo request;
9712 request.method = "POST";
bncce36dca22015-04-21 22:11:239713 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:279714 request.upload_data_stream = &upload_data_stream;
9715 request.load_flags = 0;
9716
[email protected]999dd8c2013-11-12 06:45:549717 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:099718 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9719 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419720 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]6624b4622010-03-29 19:58:369721
[email protected]999dd8c2013-11-12 06:45:549722 StaticSocketDataProvider data(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:079723 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:369724
[email protected]49639fa2011-12-20 23:22:419725 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:369726
[email protected]49639fa2011-12-20 23:22:419727 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]6624b4622010-03-29 19:58:369728 EXPECT_EQ(ERR_IO_PENDING, rv);
9729
9730 rv = callback.WaitForResult();
[email protected]999dd8c2013-11-12 06:45:549731 EXPECT_EQ(ERR_ACCESS_DENIED, rv);
[email protected]6624b4622010-03-29 19:58:369732
[email protected]dd3aa792013-07-16 19:10:239733 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:369734}
9735
[email protected]02cad5d2013-10-02 08:14:039736TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
9737 class FakeUploadElementReader : public UploadElementReader {
9738 public:
9739 FakeUploadElementReader() {}
dchengb03027d2014-10-21 12:00:209740 ~FakeUploadElementReader() override {}
[email protected]02cad5d2013-10-02 08:14:039741
9742 const CompletionCallback& callback() const { return callback_; }
9743
9744 // UploadElementReader overrides:
dchengb03027d2014-10-21 12:00:209745 int Init(const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039746 callback_ = callback;
9747 return ERR_IO_PENDING;
9748 }
avibf0746c2015-12-09 19:53:149749 uint64_t GetContentLength() const override { return 0; }
9750 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:209751 int Read(IOBuffer* buf,
9752 int buf_length,
9753 const CompletionCallback& callback) override {
[email protected]02cad5d2013-10-02 08:14:039754 return ERR_FAILED;
9755 }
9756
9757 private:
9758 CompletionCallback callback_;
9759 };
9760
9761 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:099762 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
9763 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:229764 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:039765
9766 HttpRequestInfo request;
9767 request.method = "POST";
bncce36dca22015-04-21 22:11:239768 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:039769 request.upload_data_stream = &upload_data_stream;
9770 request.load_flags = 0;
9771
danakj1fd259a02016-04-16 03:17:099772 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9773 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419774 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02cad5d2013-10-02 08:14:039775
9776 StaticSocketDataProvider data;
9777 session_deps_.socket_factory->AddSocketDataProvider(&data);
9778
9779 TestCompletionCallback callback;
9780 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9781 EXPECT_EQ(ERR_IO_PENDING, rv);
fdoray92e35a72016-06-10 15:54:559782 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:039783
9784 // Transaction is pending on request body initialization.
9785 ASSERT_FALSE(fake_reader->callback().is_null());
9786
9787 // Return Init()'s result after the transaction gets destroyed.
9788 trans.reset();
9789 fake_reader->callback().Run(OK); // Should not crash.
9790}
9791
[email protected]aeefc9e82010-02-19 16:18:279792// Tests that changes to Auth realms are treated like auth rejections.
[email protected]23e482282013-06-14 16:08:029793TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:279794 HttpRequestInfo request;
9795 request.method = "GET";
bncce36dca22015-04-21 22:11:239796 request.url = GURL("http://www.example.org/");
[email protected]aeefc9e82010-02-19 16:18:279797 request.load_flags = 0;
9798
9799 // First transaction will request a resource and receive a Basic challenge
9800 // with realm="first_realm".
9801 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239802 MockWrite(
9803 "GET / HTTP/1.1\r\n"
9804 "Host: www.example.org\r\n"
9805 "Connection: keep-alive\r\n"
9806 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279807 };
9808 MockRead data_reads1[] = {
9809 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9810 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9811 "\r\n"),
9812 };
9813
9814 // After calling trans->RestartWithAuth(), provide an Authentication header
9815 // for first_realm. The server will reject and provide a challenge with
9816 // second_realm.
9817 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239818 MockWrite(
9819 "GET / HTTP/1.1\r\n"
9820 "Host: www.example.org\r\n"
9821 "Connection: keep-alive\r\n"
9822 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
9823 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279824 };
9825 MockRead data_reads2[] = {
9826 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9827 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
9828 "\r\n"),
9829 };
9830
9831 // This again fails, and goes back to first_realm. Make sure that the
9832 // entry is removed from cache.
9833 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239834 MockWrite(
9835 "GET / HTTP/1.1\r\n"
9836 "Host: www.example.org\r\n"
9837 "Connection: keep-alive\r\n"
9838 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
9839 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279840 };
9841 MockRead data_reads3[] = {
9842 MockRead("HTTP/1.1 401 Unauthorized\r\n"
9843 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
9844 "\r\n"),
9845 };
9846
9847 // Try one last time (with the correct password) and get the resource.
9848 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:239849 MockWrite(
9850 "GET / HTTP/1.1\r\n"
9851 "Host: www.example.org\r\n"
9852 "Connection: keep-alive\r\n"
9853 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
9854 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:279855 };
9856 MockRead data_reads4[] = {
9857 MockRead("HTTP/1.1 200 OK\r\n"
9858 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:509859 "Content-Length: 5\r\n"
9860 "\r\n"
9861 "hello"),
[email protected]aeefc9e82010-02-19 16:18:279862 };
9863
9864 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
9865 data_writes1, arraysize(data_writes1));
9866 StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
9867 data_writes2, arraysize(data_writes2));
9868 StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
9869 data_writes3, arraysize(data_writes3));
9870 StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
9871 data_writes4, arraysize(data_writes4));
[email protected]bb88e1d32013-05-03 23:11:079872 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9873 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9874 session_deps_.socket_factory->AddSocketDataProvider(&data3);
9875 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:279876
[email protected]49639fa2011-12-20 23:22:419877 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:279878
danakj1fd259a02016-04-16 03:17:099879 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9880 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:419881 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:509882
[email protected]aeefc9e82010-02-19 16:18:279883 // Issue the first request with Authorize headers. There should be a
9884 // password prompt for first_realm waiting to be filled in after the
9885 // transaction completes.
[email protected]49639fa2011-12-20 23:22:419886 int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
[email protected]aeefc9e82010-02-19 16:18:279887 EXPECT_EQ(ERR_IO_PENDING, rv);
9888 rv = callback1.WaitForResult();
9889 EXPECT_EQ(OK, rv);
9890 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529891 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049892 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:529893 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:049894 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:439895 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:049896 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199897 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279898
9899 // Issue the second request with an incorrect password. There should be a
9900 // password prompt for second_realm waiting to be filled in after the
9901 // transaction completes.
[email protected]49639fa2011-12-20 23:22:419902 TestCompletionCallback callback2;
9903 rv = trans->RestartWithAuth(
9904 AuthCredentials(kFirst, kBaz), callback2.callback());
[email protected]aeefc9e82010-02-19 16:18:279905 EXPECT_EQ(ERR_IO_PENDING, rv);
9906 rv = callback2.WaitForResult();
9907 EXPECT_EQ(OK, rv);
9908 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529909 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049910 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:529911 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:049912 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:439913 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:049914 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199915 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279916
9917 // Issue the third request with another incorrect password. There should be
9918 // a password prompt for first_realm waiting to be filled in. If the password
9919 // prompt is not present, it indicates that the HttpAuthCacheEntry for
9920 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:419921 TestCompletionCallback callback3;
9922 rv = trans->RestartWithAuth(
9923 AuthCredentials(kSecond, kFou), callback3.callback());
[email protected]aeefc9e82010-02-19 16:18:279924 EXPECT_EQ(ERR_IO_PENDING, rv);
9925 rv = callback3.WaitForResult();
9926 EXPECT_EQ(OK, rv);
9927 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529928 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:049929 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:529930 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:049931 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:439932 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:049933 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:199934 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:279935
9936 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:419937 TestCompletionCallback callback4;
9938 rv = trans->RestartWithAuth(
9939 AuthCredentials(kFirst, kBar), callback4.callback());
[email protected]aeefc9e82010-02-19 16:18:279940 EXPECT_EQ(ERR_IO_PENDING, rv);
9941 rv = callback4.WaitForResult();
9942 EXPECT_EQ(OK, rv);
9943 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529944 ASSERT_TRUE(response);
9945 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:279946}
9947
bncc958faa2015-07-31 18:14:529948TEST_P(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncf33fb31b2016-01-29 15:22:269949 session_deps_.enable_alternative_service_with_different_host = false;
bncc958faa2015-07-31 18:14:529950
9951 std::string alternative_service_http_header =
9952 GetAlternativeServiceHttpHeader();
9953
9954 MockRead data_reads[] = {
9955 MockRead("HTTP/1.1 200 OK\r\n"),
9956 MockRead(alternative_service_http_header.c_str()),
9957 MockRead("\r\n"),
9958 MockRead("hello world"),
9959 MockRead(SYNCHRONOUS, OK),
9960 };
9961
9962 HttpRequestInfo request;
9963 request.method = "GET";
9964 request.url = GURL("http://www.example.org/");
9965 request.load_flags = 0;
9966
9967 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
9968
9969 session_deps_.socket_factory->AddSocketDataProvider(&data);
9970
9971 TestCompletionCallback callback;
9972
danakj1fd259a02016-04-16 03:17:099973 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9974 std::unique_ptr<HttpTransaction> trans(
bncc958faa2015-07-31 18:14:529975 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
9976
9977 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
9978 EXPECT_EQ(ERR_IO_PENDING, rv);
9979
zhongyi3d4a55e72016-04-22 20:36:469980 url::SchemeHostPort test_server("http", "www.example.org", 80);
bnc525e175a2016-06-20 12:36:409981 HttpServerProperties* http_server_properties =
9982 session->http_server_properties();
bncc958faa2015-07-31 18:14:529983 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:409984 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:529985 EXPECT_TRUE(alternative_service_vector.empty());
9986
9987 EXPECT_EQ(OK, callback.WaitForResult());
9988
9989 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529990 ASSERT_TRUE(response);
9991 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:529992 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
9993 EXPECT_FALSE(response->was_fetched_via_spdy);
9994 EXPECT_FALSE(response->was_npn_negotiated);
9995
9996 std::string response_data;
9997 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
9998 EXPECT_EQ("hello world", response_data);
9999
10000 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010001 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210002 ASSERT_EQ(1u, alternative_service_vector.size());
rdsmithebb50aa2015-11-12 03:44:3810003 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
bncc958faa2015-07-31 18:14:5210004 alternative_service_vector[0].protocol);
bnc8bef8da22016-05-30 01:28:2510005 EXPECT_EQ("www.example.org", alternative_service_vector[0].host);
bncc958faa2015-07-31 18:14:5210006 EXPECT_EQ(443, alternative_service_vector[0].port);
10007}
10008
bnce3dd56f2016-06-01 10:37:1110009// Regression test for https://crbug.com/615497.
10010TEST_P(HttpNetworkTransactionTest,
10011 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
10012 session_deps_.enable_alternative_service_for_insecure_origins = false;
10013
10014 std::string alternative_service_http_header =
10015 GetAlternativeServiceHttpHeader();
10016
10017 MockRead data_reads[] = {
10018 MockRead("HTTP/1.1 200 OK\r\n"),
10019 MockRead(alternative_service_http_header.c_str()),
10020 MockRead("\r\n"),
10021 MockRead("hello world"),
10022 MockRead(SYNCHRONOUS, OK),
10023 };
10024
10025 HttpRequestInfo request;
10026 request.method = "GET";
10027 request.url = GURL("http://www.example.org/");
10028 request.load_flags = 0;
10029
10030 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10031 session_deps_.socket_factory->AddSocketDataProvider(&data);
10032
10033 TestCompletionCallback callback;
10034
10035 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10036 std::unique_ptr<HttpTransaction> trans(
10037 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10038
10039 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4010040 HttpServerProperties* http_server_properties =
10041 session->http_server_properties();
bnce3dd56f2016-06-01 10:37:1110042 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010043 http_server_properties->GetAlternativeServices(test_server);
bnce3dd56f2016-06-01 10:37:1110044 EXPECT_TRUE(alternative_service_vector.empty());
10045
10046 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10047 EXPECT_EQ(ERR_IO_PENDING, rv);
10048 EXPECT_EQ(OK, callback.WaitForResult());
10049
10050 const HttpResponseInfo* response = trans->GetResponseInfo();
10051 ASSERT_TRUE(response);
10052 ASSERT_TRUE(response->headers);
10053 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10054 EXPECT_FALSE(response->was_fetched_via_spdy);
10055 EXPECT_FALSE(response->was_npn_negotiated);
10056
10057 std::string response_data;
10058 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10059 EXPECT_EQ("hello world", response_data);
10060
10061 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010062 http_server_properties->GetAlternativeServices(test_server);
bnce3dd56f2016-06-01 10:37:1110063 EXPECT_TRUE(alternative_service_vector.empty());
10064}
10065
bnc8bef8da22016-05-30 01:28:2510066// HTTP/2 Alternative Services should be disabled if alternative service
10067// hostname is different from that of origin.
10068// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
10069TEST_P(HttpNetworkTransactionTest,
10070 DisableHTTP2AlternativeServicesWithDifferentHost) {
10071 session_deps_.enable_alternative_service_with_different_host = true;
10072
10073 HttpRequestInfo request;
10074 request.method = "GET";
10075 request.url = GURL("http://www.example.org/");
10076 request.load_flags = 0;
10077
10078 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10079 StaticSocketDataProvider first_data;
10080 first_data.set_connect_data(mock_connect);
10081 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10082
10083 MockRead data_reads[] = {
10084 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10085 MockRead(ASYNC, OK),
10086 };
10087 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10088 0);
10089 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10090
10091 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10092
bnc525e175a2016-06-20 12:36:4010093 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2510094 session->http_server_properties();
10095 AlternativeService alternative_service(
10096 AlternateProtocolFromNextProto(GetProtocol()), "different.example.org",
10097 444);
10098 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10099 http_server_properties->SetAlternativeService(
10100 url::SchemeHostPort(request.url), alternative_service, expiration);
10101
10102 std::unique_ptr<HttpTransaction> trans(
10103 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10104 TestCompletionCallback callback;
10105
10106 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10107 // Alternative service is not used, request fails.
10108 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
10109}
10110
bnce3dd56f2016-06-01 10:37:1110111// Regression test for https://crbug.com/615497:
10112// Alternative Services should be disabled for http origin.
10113TEST_P(HttpNetworkTransactionTest,
10114 DisableAlternativeServicesForInsecureOrigin) {
10115 session_deps_.enable_alternative_service_for_insecure_origins = false;
10116
10117 HttpRequestInfo request;
10118 request.method = "GET";
10119 request.url = GURL("http://www.example.org/");
10120 request.load_flags = 0;
10121
10122 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10123 StaticSocketDataProvider first_data;
10124 first_data.set_connect_data(mock_connect);
10125 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10126
10127 MockRead data_reads[] = {
10128 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10129 MockRead(ASYNC, OK),
10130 };
10131 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads), NULL,
10132 0);
10133 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10134
10135 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10136
bnc525e175a2016-06-20 12:36:4010137 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1110138 session->http_server_properties();
10139 AlternativeService alternative_service(
10140 AlternateProtocolFromNextProto(GetProtocol()), "", 444);
10141 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10142 http_server_properties->SetAlternativeService(
10143 url::SchemeHostPort(request.url), alternative_service, expiration);
10144
10145 std::unique_ptr<HttpTransaction> trans(
10146 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10147 TestCompletionCallback callback;
10148
10149 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10150 // Alternative service is not used, request fails.
10151 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
10152}
10153
bnc4f575852015-10-14 18:35:0810154TEST_P(HttpNetworkTransactionTest, ClearAlternativeServices) {
bncf33fb31b2016-01-29 15:22:2610155 session_deps_.enable_alternative_service_with_different_host = false;
bnc4f575852015-10-14 18:35:0810156
10157 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0910158 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010159 HttpServerProperties* http_server_properties =
10160 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610161 url::SchemeHostPort test_server("http", "www.example.org", 80);
bnc4f575852015-10-14 18:35:0810162 AlternativeService alternative_service(QUIC, "", 80);
10163 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnc525e175a2016-06-20 12:36:4010164 http_server_properties->SetAlternativeService(
10165 test_server, alternative_service, expiration);
bnc4f575852015-10-14 18:35:0810166 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010167 http_server_properties->GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:0810168 EXPECT_EQ(1u, alternative_service_vector.size());
10169
10170 // Send a clear header.
10171 MockRead data_reads[] = {
10172 MockRead("HTTP/1.1 200 OK\r\n"),
10173 MockRead("Alt-Svc: clear\r\n"),
10174 MockRead("\r\n"),
10175 MockRead("hello world"),
10176 MockRead(SYNCHRONOUS, OK),
10177 };
10178 StaticSocketDataProvider data(data_reads, arraysize(data_reads), nullptr, 0);
10179 session_deps_.socket_factory->AddSocketDataProvider(&data);
10180
10181 HttpRequestInfo request;
10182 request.method = "GET";
10183 request.url = GURL("http://www.example.org/");
10184 request.load_flags = 0;
10185
10186 TestCompletionCallback callback;
10187
danakj1fd259a02016-04-16 03:17:0910188 std::unique_ptr<HttpTransaction> trans(
bnc4f575852015-10-14 18:35:0810189 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10190
10191 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10192 EXPECT_EQ(OK, callback.GetResult(rv));
10193
10194 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210195 ASSERT_TRUE(response);
10196 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0810197 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10198 EXPECT_FALSE(response->was_fetched_via_spdy);
10199 EXPECT_FALSE(response->was_npn_negotiated);
10200
10201 std::string response_data;
10202 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10203 EXPECT_EQ("hello world", response_data);
10204
10205 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010206 http_server_properties->GetAlternativeServices(test_server);
bnc4f575852015-10-14 18:35:0810207 EXPECT_TRUE(alternative_service_vector.empty());
10208}
10209
bncc958faa2015-07-31 18:14:5210210TEST_P(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeader) {
bncf33fb31b2016-01-29 15:22:2610211 session_deps_.enable_alternative_service_with_different_host = false;
bncc958faa2015-07-31 18:14:5210212
10213 MockRead data_reads[] = {
10214 MockRead("HTTP/1.1 200 OK\r\n"),
10215 MockRead("Alt-Svc: "),
10216 MockRead(GetAlternateProtocolFromParam()),
bnc44858c82015-10-16 11:57:2110217 MockRead("=\"www.example.com:443\";p=\"1.0\","),
bnc3f0118e2016-02-02 15:42:2210218 MockRead(GetAlternateProtocolFromParam()),
10219 MockRead("=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5210220 MockRead("hello world"),
10221 MockRead(SYNCHRONOUS, OK),
10222 };
10223
10224 HttpRequestInfo request;
10225 request.method = "GET";
10226 request.url = GURL("http://www.example.org/");
10227 request.load_flags = 0;
10228
10229 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
10230
10231 session_deps_.socket_factory->AddSocketDataProvider(&data);
10232
10233 TestCompletionCallback callback;
10234
danakj1fd259a02016-04-16 03:17:0910235 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10236 std::unique_ptr<HttpTransaction> trans(
bncc958faa2015-07-31 18:14:5210237 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10238
10239 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10240 EXPECT_EQ(ERR_IO_PENDING, rv);
10241
zhongyi3d4a55e72016-04-22 20:36:4610242 url::SchemeHostPort test_server("http", "www.example.org", 80);
bnc525e175a2016-06-20 12:36:4010243 HttpServerProperties* http_server_properties =
10244 session->http_server_properties();
bncc958faa2015-07-31 18:14:5210245 AlternativeServiceVector alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010246 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210247 EXPECT_TRUE(alternative_service_vector.empty());
10248
10249 EXPECT_EQ(OK, callback.WaitForResult());
10250
10251 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210252 ASSERT_TRUE(response);
10253 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5210254 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10255 EXPECT_FALSE(response->was_fetched_via_spdy);
10256 EXPECT_FALSE(response->was_npn_negotiated);
10257
10258 std::string response_data;
10259 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10260 EXPECT_EQ("hello world", response_data);
10261
10262 alternative_service_vector =
bnc525e175a2016-06-20 12:36:4010263 http_server_properties->GetAlternativeServices(test_server);
bncc958faa2015-07-31 18:14:5210264 ASSERT_EQ(2u, alternative_service_vector.size());
rdsmithebb50aa2015-11-12 03:44:3810265 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
bncc958faa2015-07-31 18:14:5210266 alternative_service_vector[0].protocol);
10267 EXPECT_EQ("www.example.com", alternative_service_vector[0].host);
10268 EXPECT_EQ(443, alternative_service_vector[0].port);
bnc3f0118e2016-02-02 15:42:2210269 EXPECT_EQ(AlternateProtocolFromNextProto(GetProtocol()),
10270 alternative_service_vector[1].protocol);
bncc958faa2015-07-31 18:14:5210271 EXPECT_EQ("www.example.org", alternative_service_vector[1].host);
10272 EXPECT_EQ(1234, alternative_service_vector[1].port);
10273}
10274
bncf33fb31b2016-01-29 15:22:2610275// When |enable_alternative_service_with_different_host| is false, do not
10276// observe alternative service entries that point to a different host.
bnc54ec34b72015-08-26 19:34:5610277TEST_P(HttpNetworkTransactionTest, DisableAlternativeServiceToDifferentHost) {
bncf33fb31b2016-01-29 15:22:2610278 session_deps_.enable_alternative_service_with_different_host = false;
bnc54ec34b72015-08-26 19:34:5610279
10280 HttpRequestInfo request;
10281 request.method = "GET";
10282 request.url = GURL("http://www.example.org/");
10283 request.load_flags = 0;
10284
10285 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10286 StaticSocketDataProvider first_data;
10287 first_data.set_connect_data(mock_connect);
10288 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
10289
10290 MockRead data_reads[] = {
10291 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
10292 MockRead(ASYNC, OK),
10293 };
10294 StaticSocketDataProvider second_data(data_reads, arraysize(data_reads),
10295 nullptr, 0);
10296 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
10297
danakj1fd259a02016-04-16 03:17:0910298 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc54ec34b72015-08-26 19:34:5610299
bnc525e175a2016-06-20 12:36:4010300 HttpServerProperties* http_server_properties =
bnc54ec34b72015-08-26 19:34:5610301 session->http_server_properties();
10302 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810303 AlternateProtocolFromNextProto(GetProtocol()), "different.example.org",
10304 80);
bnc54ec34b72015-08-26 19:34:5610305 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10306 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610307 url::SchemeHostPort(request.url), alternative_service, expiration);
bnc54ec34b72015-08-26 19:34:5610308
danakj1fd259a02016-04-16 03:17:0910309 std::unique_ptr<HttpTransaction> trans(
bnc54ec34b72015-08-26 19:34:5610310 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10311 TestCompletionCallback callback;
10312
10313 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10314 // The connetion to origin was refused, and the alternative service should not
10315 // be used (even though mock data are there), therefore the request should
10316 // fail.
10317 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.GetResult(rv));
10318}
10319
zhongyi48704c182015-12-07 07:52:0210320TEST_P(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610321 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210322 HostPortPair alternative("alternative.example.org", 443);
10323 std::string origin_url = "https://origin.example.org:443";
10324 std::string alternative_url = "https://alternative.example.org:443";
10325
10326 // Negotiate HTTP/1.1 with alternative.example.org.
10327 SSLSocketDataProvider ssl(ASYNC, OK);
10328 ssl.SetNextProto(kProtoHTTP11);
10329 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10330
10331 // HTTP/1.1 data for request.
10332 MockWrite http_writes[] = {
10333 MockWrite("GET / HTTP/1.1\r\n"
10334 "Host: alternative.example.org\r\n"
10335 "Connection: keep-alive\r\n\r\n"),
10336 };
10337
10338 MockRead http_reads[] = {
10339 MockRead("HTTP/1.1 200 OK\r\n"
10340 "Content-Type: text/html; charset=iso-8859-1\r\n"
10341 "Content-Length: 40\r\n\r\n"
10342 "first HTTP/1.1 response from alternative"),
10343 };
10344 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10345 http_writes, arraysize(http_writes));
10346 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10347
10348 StaticSocketDataProvider data_refused;
10349 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10350 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10351
zhongyi3d4a55e72016-04-22 20:36:4610352 // Set up a QUIC alternative service for server.
bncf33fb31b2016-01-29 15:22:2610353 session_deps_.enable_alternative_service_with_different_host = false;
danakj1fd259a02016-04-16 03:17:0910354 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010355 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210356 session->http_server_properties();
10357 AlternativeService alternative_service(QUIC, alternative);
10358 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610359 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5010360 expiration);
zhongyi48704c182015-12-07 07:52:0210361 // Mark the QUIC alternative service as broken.
10362 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
10363
danakj1fd259a02016-04-16 03:17:0910364 std::unique_ptr<HttpTransaction> trans(
zhongyi48704c182015-12-07 07:52:0210365 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10366 HttpRequestInfo request;
10367 request.method = "GET";
10368 request.url = GURL(origin_url);
10369 request.load_flags = 0;
10370 TestCompletionCallback callback;
10371 NetErrorDetails details;
10372 EXPECT_FALSE(details.quic_broken);
10373
10374 trans->Start(&request, callback.callback(), BoundNetLog());
10375 trans->PopulateNetErrorDetails(&details);
10376 EXPECT_TRUE(details.quic_broken);
10377}
10378
10379TEST_P(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4610380 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0210381 HostPortPair alternative1("alternative1.example.org", 443);
10382 HostPortPair alternative2("alternative2.example.org", 443);
10383 std::string origin_url = "https://origin.example.org:443";
10384 std::string alternative_url1 = "https://alternative1.example.org:443";
10385 std::string alternative_url2 = "https://alternative2.example.org:443";
10386
10387 // Negotiate HTTP/1.1 with alternative1.example.org.
10388 SSLSocketDataProvider ssl(ASYNC, OK);
10389 ssl.SetNextProto(kProtoHTTP11);
10390 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10391
10392 // HTTP/1.1 data for request.
10393 MockWrite http_writes[] = {
10394 MockWrite("GET / HTTP/1.1\r\n"
10395 "Host: alternative1.example.org\r\n"
10396 "Connection: keep-alive\r\n\r\n"),
10397 };
10398
10399 MockRead http_reads[] = {
10400 MockRead("HTTP/1.1 200 OK\r\n"
10401 "Content-Type: text/html; charset=iso-8859-1\r\n"
10402 "Content-Length: 40\r\n\r\n"
10403 "first HTTP/1.1 response from alternative1"),
10404 };
10405 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
10406 http_writes, arraysize(http_writes));
10407 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
10408
10409 StaticSocketDataProvider data_refused;
10410 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
10411 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
10412
bncf33fb31b2016-01-29 15:22:2610413 session_deps_.enable_alternative_service_with_different_host = true;
danakj1fd259a02016-04-16 03:17:0910414 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4010415 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0210416 session->http_server_properties();
10417
zhongyi3d4a55e72016-04-22 20:36:4610418 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0210419 AlternativeServiceInfoVector alternative_service_info_vector;
10420 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
10421
10422 AlternativeService alternative_service1(QUIC, alternative1);
rchdc7b9052016-03-17 20:51:5010423 AlternativeServiceInfo alternative_service_info1(alternative_service1,
zhongyi48704c182015-12-07 07:52:0210424 expiration);
10425 alternative_service_info_vector.push_back(alternative_service_info1);
10426 AlternativeService alternative_service2(QUIC, alternative2);
rchdc7b9052016-03-17 20:51:5010427 AlternativeServiceInfo alternative_service_info2(alternative_service2,
zhongyi48704c182015-12-07 07:52:0210428 expiration);
10429 alternative_service_info_vector.push_back(alternative_service_info2);
10430
10431 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4610432 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0210433
10434 // Mark one of the QUIC alternative service as broken.
10435 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
10436
10437 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610438 http_server_properties->GetAlternativeServices(server);
zhongyi48704c182015-12-07 07:52:0210439
danakj1fd259a02016-04-16 03:17:0910440 std::unique_ptr<HttpTransaction> trans(
zhongyi48704c182015-12-07 07:52:0210441 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
10442 HttpRequestInfo request;
10443 request.method = "GET";
10444 request.url = GURL(origin_url);
10445 request.load_flags = 0;
10446 TestCompletionCallback callback;
10447 NetErrorDetails details;
10448 EXPECT_FALSE(details.quic_broken);
10449
10450 trans->Start(&request, callback.callback(), BoundNetLog());
10451 trans->PopulateNetErrorDetails(&details);
10452 EXPECT_FALSE(details.quic_broken);
10453}
10454
[email protected]23e482282013-06-14 16:08:0210455TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310456 MarkBrokenAlternateProtocolAndFallback) {
bncf33fb31b2016-01-29 15:22:2610457 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]564b4912010-03-09 16:30:4210458
10459 HttpRequestInfo request;
10460 request.method = "GET";
bncce36dca22015-04-21 22:11:2310461 request.url = GURL("http://www.example.org/");
[email protected]564b4912010-03-09 16:30:4210462 request.load_flags = 0;
10463
[email protected]d973e99a2012-02-17 21:02:3610464 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4210465 StaticSocketDataProvider first_data;
10466 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710467 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]564b4912010-03-09 16:30:4210468
10469 MockRead data_reads[] = {
10470 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10471 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610472 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4210473 };
10474 StaticSocketDataProvider second_data(
10475 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710476 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4210477
danakj1fd259a02016-04-16 03:17:0910478 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4210479
bnc525e175a2016-06-20 12:36:4010480 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310481 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4610482 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1110483 // Port must be < 1024, or the header will be ignored (since initial port was
10484 // port 80 (another restricted port).
bncd9b132e2015-07-08 05:16:1010485 const AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810486 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bncd9b132e2015-07-08 05:16:1010487 666); // Port is ignored by MockConnect anyway.
bnc7dc7e1b42015-07-28 14:43:1210488 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4610489 http_server_properties->SetAlternativeService(server, alternative_service,
10490 expiration);
[email protected]564b4912010-03-09 16:30:4210491
danakj1fd259a02016-04-16 03:17:0910492 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010493 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110494 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4210495
[email protected]49639fa2011-12-20 23:22:4110496 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]564b4912010-03-09 16:30:4210497 EXPECT_EQ(ERR_IO_PENDING, rv);
10498 EXPECT_EQ(OK, callback.WaitForResult());
10499
10500 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210501 ASSERT_TRUE(response);
10502 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4210503 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10504
10505 std::string response_data;
10506 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10507 EXPECT_EQ("hello world", response_data);
10508
bncd9b132e2015-07-08 05:16:1010509 const AlternativeServiceVector alternative_service_vector =
zhongyi3d4a55e72016-04-22 20:36:4610510 http_server_properties->GetAlternativeServices(server);
bncd9b132e2015-07-08 05:16:1010511 ASSERT_EQ(1u, alternative_service_vector.size());
10512 EXPECT_EQ(alternative_service, alternative_service_vector[0]);
10513 EXPECT_TRUE(http_server_properties->IsAlternativeServiceBroken(
10514 alternative_service_vector[0]));
[email protected]564b4912010-03-09 16:30:4210515}
10516
bnc55ff9da2015-08-19 18:42:3510517// Ensure that we are not allowed to redirect traffic via an alternate protocol
10518// to an unrestricted (port >= 1024) when the original traffic was on a
10519// restricted port (port < 1024). Ensure that we can redirect in all other
10520// cases.
[email protected]23e482282013-06-14 16:08:0210521TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310522 AlternateProtocolPortRestrictedBlocked) {
bncf33fb31b2016-01-29 15:22:2610523 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110524
10525 HttpRequestInfo restricted_port_request;
10526 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310527 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110528 restricted_port_request.load_flags = 0;
10529
[email protected]d973e99a2012-02-17 21:02:3610530 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110531 StaticSocketDataProvider first_data;
10532 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710533 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110534
10535 MockRead data_reads[] = {
10536 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10537 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610538 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110539 };
10540 StaticSocketDataProvider second_data(
10541 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710542 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110543
danakj1fd259a02016-04-16 03:17:0910544 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110545
bnc525e175a2016-06-20 12:36:4010546 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310547 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110548 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:2210549 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810550 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210551 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210552 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210553 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610554 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010555 expiration);
[email protected]3912662a32011-10-04 00:51:1110556
danakj1fd259a02016-04-16 03:17:0910557 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010558 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110559 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110560
[email protected]49639fa2011-12-20 23:22:4110561 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:3610562 &restricted_port_request,
10563 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110564 EXPECT_EQ(ERR_IO_PENDING, rv);
10565 // Invalid change to unrestricted port should fail.
10566 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
[email protected]c54c6962013-02-01 04:53:1910567}
[email protected]3912662a32011-10-04 00:51:1110568
bnc55ff9da2015-08-19 18:42:3510569// Ensure that we are allowed to redirect traffic via an alternate protocol to
10570// an unrestricted (port >= 1024) when the original traffic was on a restricted
10571// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
[email protected]23e482282013-06-14 16:08:0210572TEST_P(HttpNetworkTransactionTest,
[email protected]c54c6962013-02-01 04:53:1910573 AlternateProtocolPortRestrictedPermitted) {
bncf33fb31b2016-01-29 15:22:2610574 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]bb88e1d32013-05-03 23:11:0710575 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1910576
10577 HttpRequestInfo restricted_port_request;
10578 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310579 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1910580 restricted_port_request.load_flags = 0;
10581
10582 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
10583 StaticSocketDataProvider first_data;
10584 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710585 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1910586
10587 MockRead data_reads[] = {
10588 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10589 MockRead("hello world"),
10590 MockRead(ASYNC, OK),
10591 };
10592 StaticSocketDataProvider second_data(
10593 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710594 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]c54c6962013-02-01 04:53:1910595
danakj1fd259a02016-04-16 03:17:0910596 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1910597
bnc525e175a2016-06-20 12:36:4010598 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1910599 session->http_server_properties();
10600 const int kUnrestrictedAlternatePort = 1024;
bnccacc0992015-03-20 20:22:2210601 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810602 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210603 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210604 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210605 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610606 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010607 expiration);
[email protected]c54c6962013-02-01 04:53:1910608
danakj1fd259a02016-04-16 03:17:0910609 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010610 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]c54c6962013-02-01 04:53:1910611 TestCompletionCallback callback;
10612
10613 EXPECT_EQ(ERR_IO_PENDING, trans->Start(
[email protected]262eec82013-03-19 21:01:3610614 &restricted_port_request,
10615 callback.callback(), BoundNetLog()));
[email protected]c54c6962013-02-01 04:53:1910616 // Change to unrestricted port should succeed.
10617 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110618}
10619
bnc55ff9da2015-08-19 18:42:3510620// Ensure that we are not allowed to redirect traffic via an alternate protocol
10621// to an unrestricted (port >= 1024) when the original traffic was on a
10622// restricted port (port < 1024). Ensure that we can redirect in all other
10623// cases.
[email protected]23e482282013-06-14 16:08:0210624TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310625 AlternateProtocolPortRestrictedAllowed) {
bncf33fb31b2016-01-29 15:22:2610626 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110627
10628 HttpRequestInfo restricted_port_request;
10629 restricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310630 restricted_port_request.url = GURL("http://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1110631 restricted_port_request.load_flags = 0;
10632
[email protected]d973e99a2012-02-17 21:02:3610633 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110634 StaticSocketDataProvider first_data;
10635 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710636 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110637
10638 MockRead data_reads[] = {
10639 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10640 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610641 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110642 };
10643 StaticSocketDataProvider second_data(
10644 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710645 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110646
danakj1fd259a02016-04-16 03:17:0910647 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110648
bnc525e175a2016-06-20 12:36:4010649 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310650 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110651 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210652 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810653 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210654 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210655 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210656 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610657 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010658 expiration);
[email protected]3912662a32011-10-04 00:51:1110659
danakj1fd259a02016-04-16 03:17:0910660 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010661 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110662 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110663
[email protected]49639fa2011-12-20 23:22:4110664 int rv = trans->Start(
[email protected]262eec82013-03-19 21:01:3610665 &restricted_port_request,
10666 callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110667 EXPECT_EQ(ERR_IO_PENDING, rv);
10668 // Valid change to restricted port should pass.
10669 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110670}
10671
bnc55ff9da2015-08-19 18:42:3510672// Ensure that we are not allowed to redirect traffic via an alternate protocol
10673// to an unrestricted (port >= 1024) when the original traffic was on a
10674// restricted port (port < 1024). Ensure that we can redirect in all other
10675// cases.
[email protected]23e482282013-06-14 16:08:0210676TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310677 AlternateProtocolPortUnrestrictedAllowed1) {
bncf33fb31b2016-01-29 15:22:2610678 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110679
10680 HttpRequestInfo unrestricted_port_request;
10681 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310682 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110683 unrestricted_port_request.load_flags = 0;
10684
[email protected]d973e99a2012-02-17 21:02:3610685 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110686 StaticSocketDataProvider first_data;
10687 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710688 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110689
10690 MockRead data_reads[] = {
10691 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10692 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610693 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110694 };
10695 StaticSocketDataProvider second_data(
10696 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710697 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110698
danakj1fd259a02016-04-16 03:17:0910699 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110700
bnc525e175a2016-06-20 12:36:4010701 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310702 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1110703 const int kRestrictedAlternatePort = 80;
bnccacc0992015-03-20 20:22:2210704 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810705 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210706 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210707 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210708 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610709 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010710 expiration);
[email protected]3912662a32011-10-04 00:51:1110711
danakj1fd259a02016-04-16 03:17:0910712 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010713 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110714 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110715
[email protected]49639fa2011-12-20 23:22:4110716 int rv = trans->Start(
10717 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110718 EXPECT_EQ(ERR_IO_PENDING, rv);
10719 // Valid change to restricted port should pass.
10720 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110721}
10722
bnc55ff9da2015-08-19 18:42:3510723// Ensure that we are not allowed to redirect traffic via an alternate protocol
10724// to an unrestricted (port >= 1024) when the original traffic was on a
10725// restricted port (port < 1024). Ensure that we can redirect in all other
10726// cases.
[email protected]23e482282013-06-14 16:08:0210727TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2310728 AlternateProtocolPortUnrestrictedAllowed2) {
bncf33fb31b2016-01-29 15:22:2610729 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]3912662a32011-10-04 00:51:1110730
10731 HttpRequestInfo unrestricted_port_request;
10732 unrestricted_port_request.method = "GET";
bncce36dca22015-04-21 22:11:2310733 unrestricted_port_request.url = GURL("http://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1110734 unrestricted_port_request.load_flags = 0;
10735
[email protected]d973e99a2012-02-17 21:02:3610736 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1110737 StaticSocketDataProvider first_data;
10738 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0710739 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1110740
10741 MockRead data_reads[] = {
10742 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10743 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610744 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1110745 };
10746 StaticSocketDataProvider second_data(
10747 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710748 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1110749
danakj1fd259a02016-04-16 03:17:0910750 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1110751
bnc525e175a2016-06-20 12:36:4010752 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310753 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2210754 const int kUnrestrictedAlternatePort = 1025;
bnccacc0992015-03-20 20:22:2210755 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810756 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210757 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1210758 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210759 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610760 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5010761 expiration);
[email protected]3912662a32011-10-04 00:51:1110762
danakj1fd259a02016-04-16 03:17:0910763 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010764 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4110765 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1110766
[email protected]49639fa2011-12-20 23:22:4110767 int rv = trans->Start(
10768 &unrestricted_port_request, callback.callback(), BoundNetLog());
[email protected]3912662a32011-10-04 00:51:1110769 EXPECT_EQ(ERR_IO_PENDING, rv);
10770 // Valid change to an unrestricted port should pass.
10771 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]3912662a32011-10-04 00:51:1110772}
10773
bnc55ff9da2015-08-19 18:42:3510774// Ensure that we are not allowed to redirect traffic via an alternate protocol
10775// to an unsafe port, and that we resume the second HttpStreamFactoryImpl::Job
10776// once the alternate protocol request fails.
[email protected]d7599122014-05-24 03:37:2310777TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
bncf33fb31b2016-01-29 15:22:2610778 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]eb6234e2012-01-19 01:50:0210779
10780 HttpRequestInfo request;
10781 request.method = "GET";
bncce36dca22015-04-21 22:11:2310782 request.url = GURL("http://www.example.org/");
[email protected]eb6234e2012-01-19 01:50:0210783 request.load_flags = 0;
10784
10785 // The alternate protocol request will error out before we attempt to connect,
10786 // so only the standard HTTP request will try to connect.
10787 MockRead data_reads[] = {
10788 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
10789 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610790 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0210791 };
10792 StaticSocketDataProvider data(
10793 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710794 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0210795
danakj1fd259a02016-04-16 03:17:0910796 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0210797
bnc525e175a2016-06-20 12:36:4010798 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0210799 session->http_server_properties();
10800 const int kUnsafePort = 7;
bnccacc0992015-03-20 20:22:2210801 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3810802 AlternateProtocolFromNextProto(GetProtocol()), "www.example.org",
bnccacc0992015-03-20 20:22:2210803 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1210804 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
bnccacc0992015-03-20 20:22:2210805 http_server_properties->SetAlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4610806 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0210807
danakj1fd259a02016-04-16 03:17:0910808 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010809 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]eb6234e2012-01-19 01:50:0210810 TestCompletionCallback callback;
10811
10812 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
10813 EXPECT_EQ(ERR_IO_PENDING, rv);
10814 // The HTTP request should succeed.
10815 EXPECT_EQ(OK, callback.WaitForResult());
10816
[email protected]eb6234e2012-01-19 01:50:0210817 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210818 ASSERT_TRUE(response);
10819 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0210820 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10821
10822 std::string response_data;
10823 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10824 EXPECT_EQ("hello world", response_data);
10825}
10826
[email protected]23e482282013-06-14 16:08:0210827TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
bnc1c196c6e2016-05-28 13:51:4810828 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]2ff8b312010-04-26 22:20:5410829
10830 HttpRequestInfo request;
10831 request.method = "GET";
bncce36dca22015-04-21 22:11:2310832 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5410833 request.load_flags = 0;
10834
bnc1c196c6e2016-05-28 13:51:4810835 std::string alternative_service_http_header =
10836 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4310837
[email protected]2ff8b312010-04-26 22:20:5410838 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210839 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4810840 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5210841 MockRead("\r\n"),
10842 MockRead("hello world"),
10843 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10844 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5410845
10846 StaticSocketDataProvider first_transaction(
10847 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0710848 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5410849
[email protected]8ddf8322012-02-23 18:08:0610850 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810851 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2310852 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
10853 ASSERT_TRUE(ssl.cert.get());
[email protected]bb88e1d32013-05-03 23:11:0710854 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5410855
danakj1fd259a02016-04-16 03:17:0910856 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4910857 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1310858 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5410859
danakj1fd259a02016-04-16 03:17:0910860 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5510861 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0910862 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5510863 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5410864 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310865 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5410866 };
10867
rch8e6c6c42015-05-01 14:05:1310868 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10869 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0710870 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5410871
[email protected]d973e99a2012-02-17 21:02:3610872 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5510873 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
10874 NULL, 0, NULL, 0);
10875 hanging_non_alternate_protocol_socket.set_connect_data(
10876 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0710877 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5510878 &hanging_non_alternate_protocol_socket);
10879
[email protected]49639fa2011-12-20 23:22:4110880 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5410881
danakj1fd259a02016-04-16 03:17:0910882 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10883 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5010884 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410885
[email protected]49639fa2011-12-20 23:22:4110886 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410887 EXPECT_EQ(ERR_IO_PENDING, rv);
10888 EXPECT_EQ(OK, callback.WaitForResult());
10889
10890 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210891 ASSERT_TRUE(response);
10892 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5410893 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
10894
10895 std::string response_data;
10896 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10897 EXPECT_EQ("hello world", response_data);
10898
[email protected]90499482013-06-01 00:39:5010899 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5410900
[email protected]49639fa2011-12-20 23:22:4110901 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5410902 EXPECT_EQ(ERR_IO_PENDING, rv);
10903 EXPECT_EQ(OK, callback.WaitForResult());
10904
10905 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5210906 ASSERT_TRUE(response);
10907 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0210908 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5310909 EXPECT_TRUE(response->was_fetched_via_spdy);
10910 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5410911
10912 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
10913 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5410914}
10915
[email protected]23e482282013-06-14 16:08:0210916TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
bnc1c196c6e2016-05-28 13:51:4810917 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]2d6728692011-03-12 01:39:5510918
10919 HttpRequestInfo request;
10920 request.method = "GET";
bncce36dca22015-04-21 22:11:2310921 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5510922 request.load_flags = 0;
10923
bnc1c196c6e2016-05-28 13:51:4810924 std::string alternative_service_http_header =
10925 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4310926
[email protected]2d6728692011-03-12 01:39:5510927 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5210928 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4810929 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5210930 MockRead("\r\n"),
10931 MockRead("hello world"),
10932 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
10933 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5510934 };
10935
10936 StaticSocketDataProvider first_transaction(
10937 data_reads, arraysize(data_reads), NULL, 0);
10938 // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
[email protected]bb88e1d32013-05-03 23:11:0710939 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5510940
[email protected]d973e99a2012-02-17 21:02:3610941 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
mmenkecc2298e2015-12-07 18:20:1810942 StaticSocketDataProvider hanging_socket1(NULL, 0, NULL, 0);
10943 hanging_socket1.set_connect_data(never_finishing_connect);
[email protected]2d6728692011-03-12 01:39:5510944 // Socket 2 and 3 are the hanging Alternate-Protocol and
10945 // non-Alternate-Protocol jobs from the 2nd transaction.
mmenkecc2298e2015-12-07 18:20:1810946 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
10947
10948 StaticSocketDataProvider hanging_socket2(NULL, 0, NULL, 0);
10949 hanging_socket2.set_connect_data(never_finishing_connect);
10950 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5510951
[email protected]8ddf8322012-02-23 18:08:0610952 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3810953 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2310954 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
wezca1070932016-05-26 20:30:5210955 ASSERT_TRUE(ssl.cert);
[email protected]bb88e1d32013-05-03 23:11:0710956 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5510957
danakj1fd259a02016-04-16 03:17:0910958 std::unique_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4910959 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
danakj1fd259a02016-04-16 03:17:0910960 std::unique_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4910961 spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true));
[email protected]2d6728692011-03-12 01:39:5510962 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1310963 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
[email protected]2d6728692011-03-12 01:39:5510964 };
danakj1fd259a02016-04-16 03:17:0910965 std::unique_ptr<SpdySerializedFrame> resp1(
bncb03b1092016-04-06 11:19:5510966 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0910967 std::unique_ptr<SpdySerializedFrame> data1(
bncb03b1092016-04-06 11:19:5510968 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0910969 std::unique_ptr<SpdySerializedFrame> resp2(
bncb03b1092016-04-06 11:19:5510970 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0910971 std::unique_ptr<SpdySerializedFrame> data2(
bncb03b1092016-04-06 11:19:5510972 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5510973 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1310974 CreateMockRead(*resp1, 2),
10975 CreateMockRead(*data1, 3),
10976 CreateMockRead(*resp2, 4),
10977 CreateMockRead(*data2, 5),
10978 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5510979 };
10980
rch8e6c6c42015-05-01 14:05:1310981 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
10982 arraysize(spdy_writes));
[email protected]2d6728692011-03-12 01:39:5510983 // Socket 4 is the successful Alternate-Protocol for transaction 3.
[email protected]bb88e1d32013-05-03 23:11:0710984 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5510985
10986 // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
mmenkecc2298e2015-12-07 18:20:1810987 StaticSocketDataProvider hanging_socket3(NULL, 0, NULL, 0);
10988 hanging_socket3.set_connect_data(never_finishing_connect);
10989 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5510990
danakj1fd259a02016-04-16 03:17:0910991 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4110992 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5010993 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5510994
[email protected]49639fa2011-12-20 23:22:4110995 int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5510996 EXPECT_EQ(ERR_IO_PENDING, rv);
10997 EXPECT_EQ(OK, callback1.WaitForResult());
10998
10999 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5211000 ASSERT_TRUE(response);
11001 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511002 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11003
11004 std::string response_data;
11005 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
11006 EXPECT_EQ("hello world", response_data);
11007
[email protected]49639fa2011-12-20 23:22:4111008 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5011009 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111010 rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5511011 EXPECT_EQ(ERR_IO_PENDING, rv);
11012
[email protected]49639fa2011-12-20 23:22:4111013 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5011014 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111015 rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5511016 EXPECT_EQ(ERR_IO_PENDING, rv);
11017
11018 EXPECT_EQ(OK, callback2.WaitForResult());
11019 EXPECT_EQ(OK, callback3.WaitForResult());
11020
11021 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5211022 ASSERT_TRUE(response);
11023 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211024 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511025 EXPECT_TRUE(response->was_fetched_via_spdy);
11026 EXPECT_TRUE(response->was_npn_negotiated);
11027 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
11028 EXPECT_EQ("hello!", response_data);
11029
11030 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5211031 ASSERT_TRUE(response);
11032 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211033 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5511034 EXPECT_TRUE(response->was_fetched_via_spdy);
11035 EXPECT_TRUE(response->was_npn_negotiated);
11036 ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
11037 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5511038}
11039
bnc1c196c6e2016-05-28 13:51:4811040TEST_P(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
11041 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]2d6728692011-03-12 01:39:5511042
11043 HttpRequestInfo request;
11044 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2511045 request.url = GURL("http://www.example.org/");
[email protected]2d6728692011-03-12 01:39:5511046 request.load_flags = 0;
11047
bnc1c196c6e2016-05-28 13:51:4811048 std::string alternative_service_http_header =
11049 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4311050
[email protected]2d6728692011-03-12 01:39:5511051 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211052 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4811053 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5211054 MockRead("\r\n"),
11055 MockRead("hello world"),
11056 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11057 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511058 };
11059
11060 StaticSocketDataProvider first_transaction(
11061 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711062 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5511063
[email protected]8ddf8322012-02-23 18:08:0611064 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3811065 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0711066 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5511067
[email protected]d973e99a2012-02-17 21:02:3611068 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511069 StaticSocketDataProvider hanging_alternate_protocol_socket(
11070 NULL, 0, NULL, 0);
11071 hanging_alternate_protocol_socket.set_connect_data(
11072 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711073 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511074 &hanging_alternate_protocol_socket);
11075
11076 // 2nd request is just a copy of the first one, over HTTP again.
mmenkecc2298e2015-12-07 18:20:1811077 StaticSocketDataProvider second_transaction(data_reads, arraysize(data_reads),
11078 NULL, 0);
11079 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
[email protected]2d6728692011-03-12 01:39:5511080
[email protected]49639fa2011-12-20 23:22:4111081 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5511082
danakj1fd259a02016-04-16 03:17:0911083 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11084 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011085 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5511086
[email protected]49639fa2011-12-20 23:22:4111087 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5511088 EXPECT_EQ(ERR_IO_PENDING, rv);
11089 EXPECT_EQ(OK, callback.WaitForResult());
11090
11091 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211092 ASSERT_TRUE(response);
11093 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511094 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11095
11096 std::string response_data;
11097 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11098 EXPECT_EQ("hello world", response_data);
11099
[email protected]90499482013-06-01 00:39:5011100 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2d6728692011-03-12 01:39:5511101
[email protected]49639fa2011-12-20 23:22:4111102 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2d6728692011-03-12 01:39:5511103 EXPECT_EQ(ERR_IO_PENDING, rv);
11104 EXPECT_EQ(OK, callback.WaitForResult());
11105
11106 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211107 ASSERT_TRUE(response);
11108 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5511109 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11110 EXPECT_FALSE(response->was_fetched_via_spdy);
11111 EXPECT_FALSE(response->was_npn_negotiated);
11112
11113 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11114 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5511115}
11116
[email protected]631f1322010-04-30 17:59:1111117class CapturingProxyResolver : public ProxyResolver {
11118 public:
sammce90c9212015-05-27 23:43:3511119 CapturingProxyResolver() {}
dchengb03027d2014-10-21 12:00:2011120 ~CapturingProxyResolver() override {}
[email protected]631f1322010-04-30 17:59:1111121
dchengb03027d2014-10-21 12:00:2011122 int GetProxyForURL(const GURL& url,
11123 ProxyInfo* results,
11124 const CompletionCallback& callback,
eroman9c8f4242016-02-29 21:16:5411125 RequestHandle* request,
dchengb03027d2014-10-21 12:00:2011126 const BoundNetLog& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4011127 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11128 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4211129 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1111130 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4211131 return OK;
[email protected]631f1322010-04-30 17:59:1111132 }
11133
eroman9c8f4242016-02-29 21:16:5411134 void CancelRequest(RequestHandle request) override { NOTREACHED(); }
11135
11136 LoadState GetLoadState(RequestHandle request) const override {
11137 NOTREACHED();
11138 return LOAD_STATE_IDLE;
11139 }
11140
[email protected]24476402010-07-20 20:55:1711141 const std::vector<GURL>& resolved() const { return resolved_; }
11142
11143 private:
[email protected]631f1322010-04-30 17:59:1111144 std::vector<GURL> resolved_;
11145
11146 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
11147};
11148
sammce64b2362015-04-29 03:50:2311149class CapturingProxyResolverFactory : public ProxyResolverFactory {
11150 public:
11151 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
11152 : ProxyResolverFactory(false), resolver_(resolver) {}
11153
11154 int CreateProxyResolver(
11155 const scoped_refptr<ProxyResolverScriptData>& pac_script,
danakj1fd259a02016-04-16 03:17:0911156 std::unique_ptr<ProxyResolver>* resolver,
sammce64b2362015-04-29 03:50:2311157 const net::CompletionCallback& callback,
danakj1fd259a02016-04-16 03:17:0911158 std::unique_ptr<Request>* request) override {
sammce64b2362015-04-29 03:50:2311159 resolver->reset(new ForwardingProxyResolver(resolver_));
11160 return OK;
11161 }
11162
11163 private:
11164 ProxyResolver* resolver_;
11165};
11166
bnc1c196c6e2016-05-28 13:51:4811167TEST_P(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
11168 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]631f1322010-04-30 17:59:1111169
11170 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4211171 proxy_config.set_auto_detect(true);
11172 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1111173
sammc5dd160c2015-04-02 02:43:1311174 CapturingProxyResolver capturing_proxy_resolver;
[email protected]bb88e1d32013-05-03 23:11:0711175 session_deps_.proxy_service.reset(new ProxyService(
danakj1fd259a02016-04-16 03:17:0911176 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)),
11177 base::WrapUnique(
sammce64b2362015-04-29 03:50:2311178 new CapturingProxyResolverFactory(&capturing_proxy_resolver)),
[email protected]66761b952010-06-25 21:30:3811179 NULL));
vishal.b62985ca92015-04-17 08:45:5111180 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711181 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1111182
11183 HttpRequestInfo request;
11184 request.method = "GET";
bncce36dca22015-04-21 22:11:2311185 request.url = GURL("http://www.example.org/");
[email protected]631f1322010-04-30 17:59:1111186 request.load_flags = 0;
11187
bnc1c196c6e2016-05-28 13:51:4811188 std::string alternative_service_http_header =
11189 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4311190
[email protected]631f1322010-04-30 17:59:1111191 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211192 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4811193 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5211194 MockRead("\r\n"),
11195 MockRead("hello world"),
11196 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11197 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1111198 };
11199
11200 StaticSocketDataProvider first_transaction(
11201 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711202 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]631f1322010-04-30 17:59:1111203
[email protected]8ddf8322012-02-23 18:08:0611204 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3811205 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2311206 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
wezca1070932016-05-26 20:30:5211207 ASSERT_TRUE(ssl.cert);
[email protected]bb88e1d32013-05-03 23:11:0711208 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]631f1322010-04-30 17:59:1111209
danakj1fd259a02016-04-16 03:17:0911210 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4911211 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
[email protected]631f1322010-04-30 17:59:1111212 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1311213 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2511214 "CONNECT www.example.org:443 HTTP/1.1\r\n"
11215 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1311216 "Proxy-Connection: keep-alive\r\n\r\n"),
11217 CreateMockWrite(*req, 2),
[email protected]631f1322010-04-30 17:59:1111218 };
11219
[email protected]d911f1b2010-05-05 22:39:4211220 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
11221
danakj1fd259a02016-04-16 03:17:0911222 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5511223 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0911224 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5511225 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]631f1322010-04-30 17:59:1111226 MockRead spdy_reads[] = {
mmenkee24011922015-12-17 22:12:5911227 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(*resp.get(), 3),
11228 CreateMockRead(*data.get(), 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1111229 };
11230
rch8e6c6c42015-05-01 14:05:1311231 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11232 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711233 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1111234
[email protected]d973e99a2012-02-17 21:02:3611235 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5511236 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
11237 NULL, 0, NULL, 0);
11238 hanging_non_alternate_protocol_socket.set_connect_data(
11239 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711240 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511241 &hanging_non_alternate_protocol_socket);
11242
[email protected]49639fa2011-12-20 23:22:4111243 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1111244
danakj1fd259a02016-04-16 03:17:0911245 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11246 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011247 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111248
[email protected]49639fa2011-12-20 23:22:4111249 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1111250 EXPECT_EQ(ERR_IO_PENDING, rv);
11251 EXPECT_EQ(OK, callback.WaitForResult());
11252
11253 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211254 ASSERT_TRUE(response);
11255 ASSERT_TRUE(response->headers);
[email protected]631f1322010-04-30 17:59:1111256 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311257 EXPECT_FALSE(response->was_fetched_via_spdy);
11258 EXPECT_FALSE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1111259
11260 std::string response_data;
11261 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11262 EXPECT_EQ("hello world", response_data);
11263
[email protected]90499482013-06-01 00:39:5011264 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]631f1322010-04-30 17:59:1111265
[email protected]49639fa2011-12-20 23:22:4111266 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]631f1322010-04-30 17:59:1111267 EXPECT_EQ(ERR_IO_PENDING, rv);
11268 EXPECT_EQ(OK, callback.WaitForResult());
11269
11270 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211271 ASSERT_TRUE(response);
11272 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211273 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311274 EXPECT_TRUE(response->was_fetched_via_spdy);
11275 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]631f1322010-04-30 17:59:1111276
11277 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11278 EXPECT_EQ("hello!", response_data);
sammc5dd160c2015-04-02 02:43:1311279 ASSERT_EQ(3u, capturing_proxy_resolver.resolved().size());
bncce36dca22015-04-21 22:11:2311280 EXPECT_EQ("http://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311281 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2311282 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1311283 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1111284
[email protected]029c83b62013-01-24 05:28:2011285 LoadTimingInfo load_timing_info;
11286 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
11287 TestLoadTimingNotReusedWithPac(load_timing_info,
11288 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1111289}
[email protected]631f1322010-04-30 17:59:1111290
[email protected]23e482282013-06-14 16:08:0211291TEST_P(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4811292 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
11293 session_deps_.enable_alternative_service_with_different_host = true;
[email protected]2ff8b312010-04-26 22:20:5411294
11295 HttpRequestInfo request;
11296 request.method = "GET";
bncce36dca22015-04-21 22:11:2311297 request.url = GURL("http://www.example.org/");
[email protected]2ff8b312010-04-26 22:20:5411298 request.load_flags = 0;
11299
bnc1c196c6e2016-05-28 13:51:4811300 std::string alternative_service_http_header =
11301 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4311302
[email protected]2ff8b312010-04-26 22:20:5411303 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211304 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4811305 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5211306 MockRead("\r\n"),
11307 MockRead("hello world"),
11308 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5411309 };
11310
11311 StaticSocketDataProvider first_transaction(
11312 data_reads, arraysize(data_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0711313 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2ff8b312010-04-26 22:20:5411314
[email protected]8ddf8322012-02-23 18:08:0611315 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3811316 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2311317 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
wezca1070932016-05-26 20:30:5211318 ASSERT_TRUE(ssl.cert);
[email protected]bb88e1d32013-05-03 23:11:0711319 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2ff8b312010-04-26 22:20:5411320
danakj1fd259a02016-04-16 03:17:0911321 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4911322 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1311323 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411324
danakj1fd259a02016-04-16 03:17:0911325 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5511326 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0911327 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5511328 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411329 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1311330 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411331 };
11332
rch8e6c6c42015-05-01 14:05:1311333 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
11334 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0711335 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411336
[email protected]83039bb2011-12-09 18:43:5511337 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411338
danakj1fd259a02016-04-16 03:17:0911339 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5411340
danakj1fd259a02016-04-16 03:17:0911341 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011342 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411343
[email protected]49639fa2011-12-20 23:22:4111344 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5411345 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111346 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5411347
11348 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211349 ASSERT_TRUE(response);
11350 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411351 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11352
11353 std::string response_data;
11354 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11355 EXPECT_EQ("hello world", response_data);
11356
11357 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2511358 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4011359 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5311360 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2711361 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:4211362 CreateSecureSpdySession(session.get(), key, BoundNetLog());
[email protected]02b0c342010-09-25 21:09:3811363
[email protected]90499482013-06-01 00:39:5011364 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]2ff8b312010-04-26 22:20:5411365
[email protected]49639fa2011-12-20 23:22:4111366 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]2ff8b312010-04-26 22:20:5411367 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4111368 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]2ff8b312010-04-26 22:20:5411369
11370 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211371 ASSERT_TRUE(response);
11372 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211373 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311374 EXPECT_TRUE(response->was_fetched_via_spdy);
11375 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411376
11377 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
11378 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4211379}
11380
[email protected]044de0642010-06-17 10:42:1511381// GenerateAuthToken is a mighty big test.
11382// It tests all permutation of GenerateAuthToken behavior:
11383// - Synchronous and Asynchronous completion.
11384// - OK or error on completion.
11385// - Direct connection, non-authenticating proxy, and authenticating proxy.
11386// - HTTP or HTTPS backend (to include proxy tunneling).
11387// - Non-authenticating and authenticating backend.
11388//
[email protected]fe3b7dc2012-02-03 19:52:0911389// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1511390// problems generating an auth token for an authenticating proxy, we don't
11391// need to test all permutations of the backend server).
11392//
11393// The test proceeds by going over each of the configuration cases, and
11394// potentially running up to three rounds in each of the tests. The TestConfig
11395// specifies both the configuration for the test as well as the expectations
11396// for the results.
[email protected]23e482282013-06-14 16:08:0211397TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5011398 static const char kServer[] = "http://www.example.com";
11399 static const char kSecureServer[] = "https://www.example.com";
11400 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1511401 const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
11402
11403 enum AuthTiming {
11404 AUTH_NONE,
11405 AUTH_SYNC,
11406 AUTH_ASYNC,
11407 };
11408
11409 const MockWrite kGet(
11410 "GET / HTTP/1.1\r\n"
11411 "Host: www.example.com\r\n"
11412 "Connection: keep-alive\r\n\r\n");
11413 const MockWrite kGetProxy(
11414 "GET http://www.example.com/ HTTP/1.1\r\n"
11415 "Host: www.example.com\r\n"
11416 "Proxy-Connection: keep-alive\r\n\r\n");
11417 const MockWrite kGetAuth(
11418 "GET / HTTP/1.1\r\n"
11419 "Host: www.example.com\r\n"
11420 "Connection: keep-alive\r\n"
11421 "Authorization: auth_token\r\n\r\n");
11422 const MockWrite kGetProxyAuth(
11423 "GET http://www.example.com/ HTTP/1.1\r\n"
11424 "Host: www.example.com\r\n"
11425 "Proxy-Connection: keep-alive\r\n"
11426 "Proxy-Authorization: auth_token\r\n\r\n");
11427 const MockWrite kGetAuthThroughProxy(
11428 "GET http://www.example.com/ HTTP/1.1\r\n"
11429 "Host: www.example.com\r\n"
11430 "Proxy-Connection: keep-alive\r\n"
11431 "Authorization: auth_token\r\n\r\n");
11432 const MockWrite kGetAuthWithProxyAuth(
11433 "GET http://www.example.com/ HTTP/1.1\r\n"
11434 "Host: www.example.com\r\n"
11435 "Proxy-Connection: keep-alive\r\n"
11436 "Proxy-Authorization: auth_token\r\n"
11437 "Authorization: auth_token\r\n\r\n");
11438 const MockWrite kConnect(
11439 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711440 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511441 "Proxy-Connection: keep-alive\r\n\r\n");
11442 const MockWrite kConnectProxyAuth(
11443 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1711444 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1511445 "Proxy-Connection: keep-alive\r\n"
11446 "Proxy-Authorization: auth_token\r\n\r\n");
11447
11448 const MockRead kSuccess(
11449 "HTTP/1.1 200 OK\r\n"
11450 "Content-Type: text/html; charset=iso-8859-1\r\n"
11451 "Content-Length: 3\r\n\r\n"
11452 "Yes");
11453 const MockRead kFailure(
11454 "Should not be called.");
11455 const MockRead kServerChallenge(
11456 "HTTP/1.1 401 Unauthorized\r\n"
11457 "WWW-Authenticate: Mock realm=server\r\n"
11458 "Content-Type: text/html; charset=iso-8859-1\r\n"
11459 "Content-Length: 14\r\n\r\n"
11460 "Unauthorized\r\n");
11461 const MockRead kProxyChallenge(
11462 "HTTP/1.1 407 Unauthorized\r\n"
11463 "Proxy-Authenticate: Mock realm=proxy\r\n"
11464 "Proxy-Connection: close\r\n"
11465 "Content-Type: text/html; charset=iso-8859-1\r\n"
11466 "Content-Length: 14\r\n\r\n"
11467 "Unauthorized\r\n");
11468 const MockRead kProxyConnected(
11469 "HTTP/1.1 200 Connection Established\r\n\r\n");
11470
11471 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
11472 // no constructors, but the C++ compiler on Windows warns about
11473 // unspecified data in compound literals. So, moved to using constructors,
11474 // and TestRound's created with the default constructor should not be used.
11475 struct TestRound {
11476 TestRound()
11477 : expected_rv(ERR_UNEXPECTED),
11478 extra_write(NULL),
11479 extra_read(NULL) {
11480 }
11481 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11482 int expected_rv_arg)
11483 : write(write_arg),
11484 read(read_arg),
11485 expected_rv(expected_rv_arg),
11486 extra_write(NULL),
11487 extra_read(NULL) {
11488 }
11489 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
11490 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0111491 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1511492 : write(write_arg),
11493 read(read_arg),
11494 expected_rv(expected_rv_arg),
11495 extra_write(extra_write_arg),
11496 extra_read(extra_read_arg) {
11497 }
11498 MockWrite write;
11499 MockRead read;
11500 int expected_rv;
11501 const MockWrite* extra_write;
11502 const MockRead* extra_read;
11503 };
11504
11505 static const int kNoSSL = 500;
11506
11507 struct TestConfig {
thestig9d3bb0c2015-01-24 00:49:5111508 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1511509 AuthTiming proxy_auth_timing;
11510 int proxy_auth_rv;
thestig9d3bb0c2015-01-24 00:49:5111511 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1511512 AuthTiming server_auth_timing;
11513 int server_auth_rv;
11514 int num_auth_rounds;
11515 int first_ssl_round;
11516 TestRound rounds[3];
11517 } test_configs[] = {
11518 // Non-authenticating HTTP server with a direct connection.
11519 { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
11520 { TestRound(kGet, kSuccess, OK)}},
11521 // Authenticating HTTP server with a direct connection.
11522 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
11523 { TestRound(kGet, kServerChallenge, OK),
11524 TestRound(kGetAuth, kSuccess, OK)}},
11525 { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
11526 { TestRound(kGet, kServerChallenge, OK),
11527 TestRound(kGetAuth, kFailure, kAuthErr)}},
11528 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
11529 { TestRound(kGet, kServerChallenge, OK),
11530 TestRound(kGetAuth, kSuccess, OK)}},
11531 { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
11532 { TestRound(kGet, kServerChallenge, OK),
11533 TestRound(kGetAuth, kFailure, kAuthErr)}},
11534 // Non-authenticating HTTP server through a non-authenticating proxy.
11535 { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
11536 { TestRound(kGetProxy, kSuccess, OK)}},
11537 // Authenticating HTTP server through a non-authenticating proxy.
11538 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
11539 { TestRound(kGetProxy, kServerChallenge, OK),
11540 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
11541 { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
11542 { TestRound(kGetProxy, kServerChallenge, OK),
11543 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
11544 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
11545 { TestRound(kGetProxy, kServerChallenge, OK),
11546 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
11547 { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
11548 { TestRound(kGetProxy, kServerChallenge, OK),
11549 TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
11550 // Non-authenticating HTTP server through an authenticating proxy.
11551 { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
11552 { TestRound(kGetProxy, kProxyChallenge, OK),
11553 TestRound(kGetProxyAuth, kSuccess, OK)}},
11554 { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
11555 { TestRound(kGetProxy, kProxyChallenge, OK),
11556 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
11557 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
11558 { TestRound(kGetProxy, kProxyChallenge, OK),
11559 TestRound(kGetProxyAuth, kSuccess, OK)}},
11560 { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
11561 { TestRound(kGetProxy, kProxyChallenge, OK),
11562 TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
11563 // Authenticating HTTP server through an authenticating proxy.
11564 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
11565 { TestRound(kGetProxy, kProxyChallenge, OK),
11566 TestRound(kGetProxyAuth, kServerChallenge, OK),
11567 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11568 { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
11569 { TestRound(kGetProxy, kProxyChallenge, OK),
11570 TestRound(kGetProxyAuth, kServerChallenge, OK),
11571 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11572 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
11573 { TestRound(kGetProxy, kProxyChallenge, OK),
11574 TestRound(kGetProxyAuth, kServerChallenge, OK),
11575 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11576 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
11577 { TestRound(kGetProxy, kProxyChallenge, OK),
11578 TestRound(kGetProxyAuth, kServerChallenge, OK),
11579 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11580 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
11581 { TestRound(kGetProxy, kProxyChallenge, OK),
11582 TestRound(kGetProxyAuth, kServerChallenge, OK),
11583 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11584 { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
11585 { TestRound(kGetProxy, kProxyChallenge, OK),
11586 TestRound(kGetProxyAuth, kServerChallenge, OK),
11587 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11588 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
11589 { TestRound(kGetProxy, kProxyChallenge, OK),
11590 TestRound(kGetProxyAuth, kServerChallenge, OK),
11591 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
11592 { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
11593 { TestRound(kGetProxy, kProxyChallenge, OK),
11594 TestRound(kGetProxyAuth, kServerChallenge, OK),
11595 TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
11596 // Non-authenticating HTTPS server with a direct connection.
11597 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
11598 { TestRound(kGet, kSuccess, OK)}},
11599 // Authenticating HTTPS server with a direct connection.
11600 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
11601 { TestRound(kGet, kServerChallenge, OK),
11602 TestRound(kGetAuth, kSuccess, OK)}},
11603 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
11604 { TestRound(kGet, kServerChallenge, OK),
11605 TestRound(kGetAuth, kFailure, kAuthErr)}},
11606 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
11607 { TestRound(kGet, kServerChallenge, OK),
11608 TestRound(kGetAuth, kSuccess, OK)}},
11609 { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
11610 { TestRound(kGet, kServerChallenge, OK),
11611 TestRound(kGetAuth, kFailure, kAuthErr)}},
11612 // Non-authenticating HTTPS server with a non-authenticating proxy.
11613 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
11614 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
11615 // Authenticating HTTPS server through a non-authenticating proxy.
11616 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
11617 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11618 TestRound(kGetAuth, kSuccess, OK)}},
11619 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
11620 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11621 TestRound(kGetAuth, kFailure, kAuthErr)}},
11622 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
11623 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11624 TestRound(kGetAuth, kSuccess, OK)}},
11625 { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
11626 { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
11627 TestRound(kGetAuth, kFailure, kAuthErr)}},
11628 // Non-Authenticating HTTPS server through an authenticating proxy.
11629 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
11630 { TestRound(kConnect, kProxyChallenge, OK),
11631 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
11632 { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
11633 { TestRound(kConnect, kProxyChallenge, OK),
11634 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
11635 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
11636 { TestRound(kConnect, kProxyChallenge, OK),
11637 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
11638 { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
11639 { TestRound(kConnect, kProxyChallenge, OK),
11640 TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
11641 // Authenticating HTTPS server through an authenticating proxy.
11642 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
11643 { TestRound(kConnect, kProxyChallenge, OK),
11644 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11645 &kGet, &kServerChallenge),
11646 TestRound(kGetAuth, kSuccess, OK)}},
11647 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
11648 { TestRound(kConnect, kProxyChallenge, OK),
11649 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11650 &kGet, &kServerChallenge),
11651 TestRound(kGetAuth, kFailure, kAuthErr)}},
11652 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
11653 { TestRound(kConnect, kProxyChallenge, OK),
11654 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11655 &kGet, &kServerChallenge),
11656 TestRound(kGetAuth, kSuccess, OK)}},
11657 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
11658 { TestRound(kConnect, kProxyChallenge, OK),
11659 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11660 &kGet, &kServerChallenge),
11661 TestRound(kGetAuth, kFailure, kAuthErr)}},
11662 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
11663 { TestRound(kConnect, kProxyChallenge, OK),
11664 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11665 &kGet, &kServerChallenge),
11666 TestRound(kGetAuth, kSuccess, OK)}},
11667 { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
11668 { TestRound(kConnect, kProxyChallenge, OK),
11669 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11670 &kGet, &kServerChallenge),
11671 TestRound(kGetAuth, kFailure, kAuthErr)}},
11672 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
11673 { TestRound(kConnect, kProxyChallenge, OK),
11674 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11675 &kGet, &kServerChallenge),
11676 TestRound(kGetAuth, kSuccess, OK)}},
11677 { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
11678 { TestRound(kConnect, kProxyChallenge, OK),
11679 TestRound(kConnectProxyAuth, kProxyConnected, OK,
11680 &kGet, &kServerChallenge),
11681 TestRound(kGetAuth, kFailure, kAuthErr)}},
11682 };
11683
viettrungluue4a8b882014-10-16 06:17:3811684 for (size_t i = 0; i < arraysize(test_configs); ++i) {
[email protected]2d01c262011-08-11 23:07:0811685 HttpAuthHandlerMock::Factory* auth_factory(
11686 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0711687 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4911688 SSLInfo empty_ssl_info;
[email protected]044de0642010-06-17 10:42:1511689 const TestConfig& test_config = test_configs[i];
[email protected]65d34382010-07-01 18:12:2611690
11691 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1511692 if (test_config.proxy_auth_timing != AUTH_NONE) {
[email protected]2d01c262011-08-11 23:07:0811693 for (int n = 0; n < 2; n++) {
11694 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
11695 std::string auth_challenge = "Mock realm=proxy";
11696 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2411697 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11698 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0811699 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
asanka5ffd5d72016-03-23 16:20:4911700 empty_ssl_info, origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0811701 auth_handler->SetGenerateExpectation(
11702 test_config.proxy_auth_timing == AUTH_ASYNC,
11703 test_config.proxy_auth_rv);
11704 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
11705 }
[email protected]044de0642010-06-17 10:42:1511706 }
11707 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0011708 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1511709 std::string auth_challenge = "Mock realm=server";
11710 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2411711 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11712 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1511713 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
asanka5ffd5d72016-03-23 16:20:4911714 empty_ssl_info, origin, BoundNetLog());
[email protected]044de0642010-06-17 10:42:1511715 auth_handler->SetGenerateExpectation(
11716 test_config.server_auth_timing == AUTH_ASYNC,
11717 test_config.server_auth_rv);
[email protected]2d01c262011-08-11 23:07:0811718 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1511719 }
11720 if (test_config.proxy_url) {
rdsmith82957ad2015-09-16 19:42:0311721 session_deps_.proxy_service =
11722 ProxyService::CreateFixed(test_config.proxy_url);
[email protected]044de0642010-06-17 10:42:1511723 } else {
rdsmith82957ad2015-09-16 19:42:0311724 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1511725 }
11726
11727 HttpRequestInfo request;
11728 request.method = "GET";
11729 request.url = GURL(test_config.server_url);
11730 request.load_flags = 0;
11731
danakj1fd259a02016-04-16 03:17:0911732 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1511733
rchcb68dc62015-05-21 04:45:3611734 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
11735
11736 std::vector<std::vector<MockRead>> mock_reads(1);
11737 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1511738 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
11739 const TestRound& read_write_round = test_config.rounds[round];
11740
11741 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3611742 mock_reads.back().push_back(read_write_round.read);
11743 mock_writes.back().push_back(read_write_round.write);
11744
11745 // kProxyChallenge uses Proxy-Connection: close which means that the
11746 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5411747 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3611748 mock_reads.push_back(std::vector<MockRead>());
11749 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1511750 }
11751
rchcb68dc62015-05-21 04:45:3611752 if (read_write_round.extra_read) {
11753 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1511754 }
rchcb68dc62015-05-21 04:45:3611755 if (read_write_round.extra_write) {
11756 mock_writes.back().push_back(*read_write_round.extra_write);
11757 }
[email protected]044de0642010-06-17 10:42:1511758
11759 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1511760 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0711761 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1511762 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3611763 }
[email protected]044de0642010-06-17 10:42:1511764
danakj1fd259a02016-04-16 03:17:0911765 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3611766 for (size_t i = 0; i < mock_reads.size(); ++i) {
danakj1fd259a02016-04-16 03:17:0911767 data_providers.push_back(base::WrapUnique(new StaticSocketDataProvider(
davidben5f8b6bc2015-11-25 03:19:5411768 mock_reads[i].data(), mock_reads[i].size(), mock_writes[i].data(),
olli.raula525048c2015-12-10 07:38:3211769 mock_writes[i].size())));
rchcb68dc62015-05-21 04:45:3611770 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3211771 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3611772 }
11773
mmenkecc2298e2015-12-07 18:20:1811774 // Transaction must be created after DataProviders, so it's destroyed before
11775 // they are as well.
11776 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11777
rchcb68dc62015-05-21 04:45:3611778 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
11779 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1511780 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4111781 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1511782 int rv;
11783 if (round == 0) {
[email protected]49639fa2011-12-20 23:22:4111784 rv = trans.Start(&request, callback.callback(), BoundNetLog());
[email protected]044de0642010-06-17 10:42:1511785 } else {
[email protected]49639fa2011-12-20 23:22:4111786 rv = trans.RestartWithAuth(
11787 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1511788 }
11789 if (rv == ERR_IO_PENDING)
11790 rv = callback.WaitForResult();
11791
11792 // Compare results with expected data.
11793 EXPECT_EQ(read_write_round.expected_rv, rv);
[email protected]0b0bf032010-09-21 18:08:5011794 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5511795 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1511796 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
11797 continue;
11798 }
11799 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5211800 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1511801 } else {
wezca1070932016-05-26 20:30:5211802 EXPECT_FALSE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1511803 }
11804 }
[email protected]e5ae96a2010-04-14 20:12:4511805 }
11806}
11807
[email protected]23e482282013-06-14 16:08:0211808TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1411809 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1411810 HttpAuthHandlerMock::Factory* auth_factory(
11811 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0711812 session_deps_.http_auth_handler_factory.reset(auth_factory);
rdsmith82957ad2015-09-16 19:42:0311813 session_deps_.proxy_service = ProxyService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0711814 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
11815 session_deps_.host_resolver->set_synchronous_mode(true);
[email protected]c871bce92010-07-15 21:51:1411816
11817 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
11818 auth_handler->set_connection_based(true);
11819 std::string auth_challenge = "Mock realm=server";
11820 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2411821 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
11822 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4911823 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1411824 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
asanka5ffd5d72016-03-23 16:20:4911825 empty_ssl_info, origin, BoundNetLog());
[email protected]2d01c262011-08-11 23:07:0811826 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1411827
[email protected]c871bce92010-07-15 21:51:1411828 int rv = OK;
11829 const HttpResponseInfo* response = NULL;
11830 HttpRequestInfo request;
11831 request.method = "GET";
11832 request.url = origin;
11833 request.load_flags = 0;
[email protected]cb9bf6ca2011-01-28 13:15:2711834
danakj1fd259a02016-04-16 03:17:0911835 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1011836
11837 // Use a TCP Socket Pool with only one connection per group. This is used
11838 // to validate that the TCP socket is not released to the pool between
11839 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4211840 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2811841 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1011842 50, // Max sockets for pool
11843 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2111844 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
11845 NULL, session_deps_.net_log);
danakj1fd259a02016-04-16 03:17:0911846 std::unique_ptr<MockClientSocketPoolManager> mock_pool_manager(
[email protected]831e4a32013-11-14 02:14:4411847 new MockClientSocketPoolManager);
[email protected]a42dbd142011-11-17 16:42:0211848 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4811849 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1011850
danakj1fd259a02016-04-16 03:17:0911851 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5011852 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111853 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1411854
11855 const MockWrite kGet(
11856 "GET / HTTP/1.1\r\n"
11857 "Host: www.example.com\r\n"
11858 "Connection: keep-alive\r\n\r\n");
11859 const MockWrite kGetAuth(
11860 "GET / HTTP/1.1\r\n"
11861 "Host: www.example.com\r\n"
11862 "Connection: keep-alive\r\n"
11863 "Authorization: auth_token\r\n\r\n");
11864
11865 const MockRead kServerChallenge(
11866 "HTTP/1.1 401 Unauthorized\r\n"
11867 "WWW-Authenticate: Mock realm=server\r\n"
11868 "Content-Type: text/html; charset=iso-8859-1\r\n"
11869 "Content-Length: 14\r\n\r\n"
11870 "Unauthorized\r\n");
11871 const MockRead kSuccess(
11872 "HTTP/1.1 200 OK\r\n"
11873 "Content-Type: text/html; charset=iso-8859-1\r\n"
11874 "Content-Length: 3\r\n\r\n"
11875 "Yes");
11876
11877 MockWrite writes[] = {
11878 // First round
11879 kGet,
11880 // Second round
11881 kGetAuth,
11882 // Third round
11883 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3011884 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1011885 kGetAuth,
11886 // Competing request
11887 kGet,
[email protected]c871bce92010-07-15 21:51:1411888 };
11889 MockRead reads[] = {
11890 // First round
11891 kServerChallenge,
11892 // Second round
11893 kServerChallenge,
11894 // Third round
[email protected]eca50e122010-09-11 14:03:3011895 kServerChallenge,
11896 // Fourth round
[email protected]c871bce92010-07-15 21:51:1411897 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1011898 // Competing response
11899 kSuccess,
[email protected]c871bce92010-07-15 21:51:1411900 };
11901 StaticSocketDataProvider data_provider(reads, arraysize(reads),
11902 writes, arraysize(writes));
[email protected]bb88e1d32013-05-03 23:11:0711903 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1411904
thestig9d3bb0c2015-01-24 00:49:5111905 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1011906
11907 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1411908 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111909 rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]c871bce92010-07-15 21:51:1411910 if (rv == ERR_IO_PENDING)
11911 rv = callback.WaitForResult();
11912 EXPECT_EQ(OK, rv);
11913 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211914 ASSERT_TRUE(response);
11915 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811916 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411917
[email protected]7ef4cbbb2011-02-06 11:19:1011918 // In between rounds, another request comes in for the same domain.
11919 // It should not be able to grab the TCP socket that trans has already
11920 // claimed.
danakj1fd259a02016-04-16 03:17:0911921 std::unique_ptr<HttpTransaction> trans_compete(
[email protected]90499482013-06-01 00:39:5011922 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4111923 TestCompletionCallback callback_compete;
11924 rv = trans_compete->Start(
11925 &request, callback_compete.callback(), BoundNetLog());
[email protected]7ef4cbbb2011-02-06 11:19:1011926 EXPECT_EQ(ERR_IO_PENDING, rv);
11927 // callback_compete.WaitForResult at this point would stall forever,
11928 // since the HttpNetworkTransaction does not release the request back to
11929 // the pool until after authentication completes.
11930
11931 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1411932 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111933 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1411934 if (rv == ERR_IO_PENDING)
11935 rv = callback.WaitForResult();
11936 EXPECT_EQ(OK, rv);
11937 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211938 ASSERT_TRUE(response);
11939 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811940 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411941
[email protected]7ef4cbbb2011-02-06 11:19:1011942 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1411943 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111944 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1411945 if (rv == ERR_IO_PENDING)
11946 rv = callback.WaitForResult();
11947 EXPECT_EQ(OK, rv);
11948 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211949 ASSERT_TRUE(response);
11950 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811951 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]eca50e122010-09-11 14:03:3011952
[email protected]7ef4cbbb2011-02-06 11:19:1011953 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3011954 auth_handler->SetGenerateExpectation(false, OK);
[email protected]49639fa2011-12-20 23:22:4111955 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3011956 if (rv == ERR_IO_PENDING)
11957 rv = callback.WaitForResult();
11958 EXPECT_EQ(OK, rv);
11959 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211960 ASSERT_TRUE(response);
11961 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2811962 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1011963
11964 // Read the body since the fourth round was successful. This will also
11965 // release the socket back to the pool.
11966 scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
[email protected]90499482013-06-01 00:39:5011967 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011968 if (rv == ERR_IO_PENDING)
11969 rv = callback.WaitForResult();
11970 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5011971 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011972 EXPECT_EQ(0, rv);
11973 // There are still 0 idle sockets, since the trans_compete transaction
11974 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2811975 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1011976
11977 // The competing request can now finish. Wait for the headers and then
11978 // read the body.
11979 rv = callback_compete.WaitForResult();
11980 EXPECT_EQ(OK, rv);
[email protected]90499482013-06-01 00:39:5011981 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011982 if (rv == ERR_IO_PENDING)
11983 rv = callback.WaitForResult();
11984 EXPECT_EQ(3, rv);
[email protected]90499482013-06-01 00:39:5011985 rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1011986 EXPECT_EQ(0, rv);
11987
11988 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2811989 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1411990}
11991
[email protected]65041fa2010-05-21 06:56:5311992// This tests the case that a request is issued via http instead of spdy after
11993// npn is negotiated.
[email protected]23e482282013-06-14 16:08:0211994TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
bncf33fb31b2016-01-29 15:22:2611995 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]d7599122014-05-24 03:37:2311996
[email protected]65041fa2010-05-21 06:56:5311997 HttpRequestInfo request;
11998 request.method = "GET";
bncce36dca22015-04-21 22:11:2311999 request.url = GURL("https://www.example.org/");
[email protected]65041fa2010-05-21 06:56:5312000 request.load_flags = 0;
12001
12002 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2312003 MockWrite(
12004 "GET / HTTP/1.1\r\n"
12005 "Host: www.example.org\r\n"
12006 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5312007 };
12008
bnc1c196c6e2016-05-28 13:51:4812009 std::string alternative_service_http_header =
12010 GetAlternativeServiceHttpHeader();
[email protected]8a0fc822013-06-27 20:52:4312011
[email protected]65041fa2010-05-21 06:56:5312012 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212013 MockRead("HTTP/1.1 200 OK\r\n"),
bnc1c196c6e2016-05-28 13:51:4812014 MockRead(alternative_service_http_header.c_str()),
bncc958faa2015-07-31 18:14:5212015 MockRead("\r\n"),
12016 MockRead("hello world"),
12017 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5312018 };
12019
[email protected]8ddf8322012-02-23 18:08:0612020 SSLSocketDataProvider ssl(ASYNC, OK);
davidben6974bf72015-04-27 17:52:4812021 ssl.SetNextProto(kProtoHTTP11);
[email protected]65041fa2010-05-21 06:56:5312022
[email protected]bb88e1d32013-05-03 23:11:0712023 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5312024
12025 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
12026 data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712027 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5312028
[email protected]49639fa2011-12-20 23:22:4112029 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5312030
danakj1fd259a02016-04-16 03:17:0912031 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12032 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012033 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]65041fa2010-05-21 06:56:5312034
[email protected]49639fa2011-12-20 23:22:4112035 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]65041fa2010-05-21 06:56:5312036
12037 EXPECT_EQ(ERR_IO_PENDING, rv);
12038 EXPECT_EQ(OK, callback.WaitForResult());
12039
12040 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212041 ASSERT_TRUE(response);
12042 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5312043 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12044
12045 std::string response_data;
12046 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
12047 EXPECT_EQ("hello world", response_data);
12048
12049 EXPECT_FALSE(response->was_fetched_via_spdy);
12050 EXPECT_TRUE(response->was_npn_negotiated);
[email protected]65041fa2010-05-21 06:56:5312051}
[email protected]26ef6582010-06-24 02:30:4712052
bnc55ff9da2015-08-19 18:42:3512053// Simulate the SSL handshake completing with an NPN negotiation followed by an
12054// immediate server closing of the socket.
12055// Regression test for https://crbug.com/46369.
[email protected]23e482282013-06-14 16:08:0212056TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
bncf33fb31b2016-01-29 15:22:2612057 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]26ef6582010-06-24 02:30:4712058
12059 HttpRequestInfo request;
12060 request.method = "GET";
bncce36dca22015-04-21 22:11:2312061 request.url = GURL("https://www.example.org/");
[email protected]26ef6582010-06-24 02:30:4712062 request.load_flags = 0;
12063
[email protected]8ddf8322012-02-23 18:08:0612064 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812065 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712066 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4712067
danakj1fd259a02016-04-16 03:17:0912068 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4912069 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
rch8e6c6c42015-05-01 14:05:1312070 MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
[email protected]26ef6582010-06-24 02:30:4712071
12072 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612073 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4712074 };
12075
rch8e6c6c42015-05-01 14:05:1312076 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12077 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712078 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4712079
[email protected]49639fa2011-12-20 23:22:4112080 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4712081
danakj1fd259a02016-04-16 03:17:0912082 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12083 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012084 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]26ef6582010-06-24 02:30:4712085
[email protected]49639fa2011-12-20 23:22:4112086 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]26ef6582010-06-24 02:30:4712087 EXPECT_EQ(ERR_IO_PENDING, rv);
12088 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
[email protected]26ef6582010-06-24 02:30:4712089}
[email protected]65d34382010-07-01 18:12:2612090
[email protected]795cbf82013-07-22 09:37:2712091// A subclass of HttpAuthHandlerMock that records the request URL when
12092// it gets it. This is needed since the auth handler may get destroyed
12093// before we get a chance to query it.
12094class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
12095 public:
12096 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
12097
dchengb03027d2014-10-21 12:00:2012098 ~UrlRecordingHttpAuthHandlerMock() override {}
[email protected]795cbf82013-07-22 09:37:2712099
12100 protected:
dchengb03027d2014-10-21 12:00:2012101 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
12102 const HttpRequestInfo* request,
12103 const CompletionCallback& callback,
12104 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2712105 *url_ = request->url;
12106 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
12107 credentials, request, callback, auth_token);
12108 }
12109
12110 private:
12111 GURL* url_;
12112};
12113
bnc55ff9da2015-08-19 18:42:3512114// This test ensures that the URL passed into the proxy is upgraded to https
12115// when doing an Alternate Protocol upgrade.
bnc1c196c6e2016-05-28 13:51:4812116TEST_P(HttpNetworkTransactionTest, SpdyAlternativeServiceThroughProxy) {
bncf33fb31b2016-01-29 15:22:2612117 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]f45c1ee2010-08-03 00:54:3012118
rdsmith82957ad2015-09-16 19:42:0312119 session_deps_.proxy_service =
12120 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112121 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0712122 session_deps_.net_log = &net_log;
[email protected]795cbf82013-07-22 09:37:2712123 GURL request_url;
12124 {
12125 HttpAuthHandlerMock::Factory* auth_factory =
12126 new HttpAuthHandlerMock::Factory();
12127 UrlRecordingHttpAuthHandlerMock* auth_handler =
12128 new UrlRecordingHttpAuthHandlerMock(&request_url);
12129 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
12130 auth_factory->set_do_init_from_challenge(true);
12131 session_deps_.http_auth_handler_factory.reset(auth_factory);
12132 }
[email protected]f45c1ee2010-08-03 00:54:3012133
12134 HttpRequestInfo request;
12135 request.method = "GET";
bncce36dca22015-04-21 22:11:2312136 request.url = GURL("http://www.example.org");
[email protected]f45c1ee2010-08-03 00:54:3012137 request.load_flags = 0;
12138
12139 // First round goes unauthenticated through the proxy.
12140 MockWrite data_writes_1[] = {
bncce36dca22015-04-21 22:11:2312141 MockWrite(
12142 "GET http://www.example.org/ HTTP/1.1\r\n"
12143 "Host: www.example.org\r\n"
12144 "Proxy-Connection: keep-alive\r\n"
12145 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3012146 };
12147 MockRead data_reads_1[] = {
bnc1c196c6e2016-05-28 13:51:4812148 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12149 MockRead("HTTP/1.1 200 OK\r\n"),
12150 MockRead("Alt-Svc: "),
12151 MockRead(GetAlternateProtocolFromParam()),
12152 MockRead("=\":443\"\r\n"),
12153 MockRead("Proxy-Connection: close\r\n"),
12154 MockRead("\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3012155 };
12156 StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
12157 data_writes_1, arraysize(data_writes_1));
12158
bncce36dca22015-04-21 22:11:2312159 // Second round tries to tunnel to www.example.org due to the
[email protected]f45c1ee2010-08-03 00:54:3012160 // Alternate-Protocol announcement in the first round. It fails due
12161 // to a proxy authentication challenge.
bncce36dca22015-04-21 22:11:2312162 // After the failure, a tunnel is established to www.example.org using
[email protected]394816e92010-08-03 07:38:5912163 // Proxy-Authorization headers. There is then a SPDY request round.
12164 //
[email protected]fe3b7dc2012-02-03 19:52:0912165 // NOTE: Despite the "Proxy-Connection: Close", these are done on the
12166 // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
12167 // does a Disconnect and Connect on the same socket, rather than trying
12168 // to obtain a new one.
12169 //
[email protected]394816e92010-08-03 07:38:5912170 // NOTE: Originally, the proxy response to the second CONNECT request
12171 // simply returned another 407 so the unit test could skip the SSL connection
12172 // establishment and SPDY framing issues. Alas, the
12173 // retry-http-when-alternate-protocol fails logic kicks in, which was more
[email protected]f45c1ee2010-08-03 00:54:3012174 // complicated to set up expectations for than the SPDY session.
[email protected]394816e92010-08-03 07:38:5912175
danakj1fd259a02016-04-16 03:17:0912176 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4912177 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
danakj1fd259a02016-04-16 03:17:0912178 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5512179 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0912180 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5512181 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]f45c1ee2010-08-03 00:54:3012182
[email protected]394816e92010-08-03 07:38:5912183 MockWrite data_writes_2[] = {
bncce36dca22015-04-21 22:11:2312184 // First connection attempt without Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1312185 MockWrite(ASYNC, 0,
12186 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712187 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312188 "Proxy-Connection: keep-alive\r\n"
12189 "\r\n"),
[email protected]394816e92010-08-03 07:38:5912190
bncce36dca22015-04-21 22:11:2312191 // Second connection attempt with Proxy-Authorization.
rch8e6c6c42015-05-01 14:05:1312192 MockWrite(ASYNC, 2,
12193 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712194 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312195 "Proxy-Connection: keep-alive\r\n"
12196 "Proxy-Authorization: auth_token\r\n"
12197 "\r\n"),
[email protected]f45c1ee2010-08-03 00:54:3012198
bncce36dca22015-04-21 22:11:2312199 // SPDY request
rch8e6c6c42015-05-01 14:05:1312200 CreateMockWrite(*req, 4),
[email protected]f45c1ee2010-08-03 00:54:3012201 };
[email protected]394816e92010-08-03 07:38:5912202 MockRead data_reads_2[] = {
rch8e6c6c42015-05-01 14:05:1312203 // First connection attempt fails
mmenkee71e15332015-10-07 16:39:5412204 MockRead(ASYNC, 1,
12205 "HTTP/1.1 407 Unauthorized\r\n"
12206 "Proxy-Authenticate: Mock\r\n"
12207 "Content-Length: 0\r\n"
12208 "Proxy-Connection: keep-alive\r\n"
12209 "\r\n"),
[email protected]394816e92010-08-03 07:38:5912210
rch8e6c6c42015-05-01 14:05:1312211 // Second connection attempt passes
mmenkee71e15332015-10-07 16:39:5412212 MockRead(ASYNC, 3, "HTTP/1.1 200 Connected\r\n\r\n"),
[email protected]394816e92010-08-03 07:38:5912213
rch8e6c6c42015-05-01 14:05:1312214 // SPDY response
mmenkee71e15332015-10-07 16:39:5412215 CreateMockRead(*resp.get(), 5), CreateMockRead(*data.get(), 6),
rch8e6c6c42015-05-01 14:05:1312216 MockRead(ASYNC, 0, 0, 7),
[email protected]394816e92010-08-03 07:38:5912217 };
rch8e6c6c42015-05-01 14:05:1312218 SequencedSocketData data_2(data_reads_2, arraysize(data_reads_2),
12219 data_writes_2, arraysize(data_writes_2));
[email protected]f45c1ee2010-08-03 00:54:3012220
[email protected]8ddf8322012-02-23 18:08:0612221 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812222 ssl.SetNextProto(GetProtocol());
bncce36dca22015-04-21 22:11:2312223 ssl.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
wezca1070932016-05-26 20:30:5212224 ASSERT_TRUE(ssl.cert);
[email protected]f45c1ee2010-08-03 00:54:3012225
[email protected]d973e99a2012-02-17 21:02:3612226 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
[email protected]2d6728692011-03-12 01:39:5512227 StaticSocketDataProvider hanging_non_alternate_protocol_socket(
12228 NULL, 0, NULL, 0);
12229 hanging_non_alternate_protocol_socket.set_connect_data(
12230 never_finishing_connect);
12231
[email protected]bb88e1d32013-05-03 23:11:0712232 session_deps_.socket_factory->AddSocketDataProvider(&data_1);
12233 session_deps_.socket_factory->AddSocketDataProvider(&data_2);
12234 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12235 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512236 &hanging_non_alternate_protocol_socket);
danakj1fd259a02016-04-16 03:17:0912237 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f45c1ee2010-08-03 00:54:3012238
12239 // First round should work and provide the Alternate-Protocol state.
[email protected]49639fa2011-12-20 23:22:4112240 TestCompletionCallback callback_1;
danakj1fd259a02016-04-16 03:17:0912241 std::unique_ptr<HttpTransaction> trans_1(
[email protected]90499482013-06-01 00:39:5012242 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4112243 int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3012244 EXPECT_EQ(ERR_IO_PENDING, rv);
12245 EXPECT_EQ(OK, callback_1.WaitForResult());
12246
12247 // Second round should attempt a tunnel connect and get an auth challenge.
[email protected]49639fa2011-12-20 23:22:4112248 TestCompletionCallback callback_2;
danakj1fd259a02016-04-16 03:17:0912249 std::unique_ptr<HttpTransaction> trans_2(
[email protected]90499482013-06-01 00:39:5012250 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]49639fa2011-12-20 23:22:4112251 rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
[email protected]f45c1ee2010-08-03 00:54:3012252 EXPECT_EQ(ERR_IO_PENDING, rv);
12253 EXPECT_EQ(OK, callback_2.WaitForResult());
12254 const HttpResponseInfo* response = trans_2->GetResponseInfo();
wezca1070932016-05-26 20:30:5212255 ASSERT_TRUE(response);
12256 ASSERT_TRUE(response->auth_challenge);
[email protected]f45c1ee2010-08-03 00:54:3012257
12258 // Restart with auth. Tunnel should work and response received.
[email protected]49639fa2011-12-20 23:22:4112259 TestCompletionCallback callback_3;
12260 rv = trans_2->RestartWithAuth(
12261 AuthCredentials(kFoo, kBar), callback_3.callback());
[email protected]f45c1ee2010-08-03 00:54:3012262 EXPECT_EQ(ERR_IO_PENDING, rv);
12263 EXPECT_EQ(OK, callback_3.WaitForResult());
12264
12265 // After all that work, these two lines (or actually, just the scheme) are
12266 // what this test is all about. Make sure it happens correctly.
[email protected]f45c1ee2010-08-03 00:54:3012267 EXPECT_EQ("https", request_url.scheme());
bncce36dca22015-04-21 22:11:2312268 EXPECT_EQ("www.example.org", request_url.host());
[email protected]f45c1ee2010-08-03 00:54:3012269
[email protected]029c83b62013-01-24 05:28:2012270 LoadTimingInfo load_timing_info;
12271 EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
12272 TestLoadTimingNotReusedWithPac(load_timing_info,
12273 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]8e6441ca2010-08-19 05:56:3812274}
12275
12276// Test that if we cancel the transaction as the connection is completing, that
12277// everything tears down correctly.
[email protected]23e482282013-06-14 16:08:0212278TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3812279 // Setup everything about the connection to complete synchronously, so that
12280 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
12281 // for is the callback from the HttpStreamRequest.
12282 // Then cancel the transaction.
12283 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3612284 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3812285 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0612286 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
12287 MockRead(SYNCHRONOUS, "hello world"),
12288 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3812289 };
12290
[email protected]8e6441ca2010-08-19 05:56:3812291 HttpRequestInfo request;
12292 request.method = "GET";
bncce36dca22015-04-21 22:11:2312293 request.url = GURL("http://www.example.org/");
[email protected]8e6441ca2010-08-19 05:56:3812294 request.load_flags = 0;
12295
[email protected]bb88e1d32013-05-03 23:11:0712296 session_deps_.host_resolver->set_synchronous_mode(true);
danakj1fd259a02016-04-16 03:17:0912297 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12298 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4112299 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]cb9bf6ca2011-01-28 13:15:2712300
[email protected]8e6441ca2010-08-19 05:56:3812301 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12302 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712303 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3812304
[email protected]49639fa2011-12-20 23:22:4112305 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3812306
vishal.b62985ca92015-04-17 08:45:5112307 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4112308 int rv = trans->Start(&request, callback.callback(), log.bound());
[email protected]8e6441ca2010-08-19 05:56:3812309 EXPECT_EQ(ERR_IO_PENDING, rv);
12310 trans.reset(); // Cancel the transaction here.
12311
fdoray92e35a72016-06-10 15:54:5512312 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3012313}
12314
[email protected]ecab6e052014-05-16 14:58:1212315// Test that if a transaction is cancelled after receiving the headers, the
12316// stream is drained properly and added back to the socket pool. The main
12317// purpose of this test is to make sure that an HttpStreamParser can be read
12318// from after the HttpNetworkTransaction and the objects it owns have been
12319// deleted.
12320// See http://crbug.com/368418
12321TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
12322 MockRead data_reads[] = {
12323 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
12324 MockRead(ASYNC, "Content-Length: 2\r\n"),
12325 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
12326 MockRead(ASYNC, "1"),
12327 // 2 async reads are necessary to trigger a ReadResponseBody call after the
12328 // HttpNetworkTransaction has been deleted.
12329 MockRead(ASYNC, "2"),
12330 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
12331 };
12332 StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
12333 session_deps_.socket_factory->AddSocketDataProvider(&data);
12334
danakj1fd259a02016-04-16 03:17:0912335 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1212336
12337 {
12338 HttpRequestInfo request;
12339 request.method = "GET";
bncce36dca22015-04-21 22:11:2312340 request.url = GURL("http://www.example.org/");
[email protected]ecab6e052014-05-16 14:58:1212341 request.load_flags = 0;
12342
dcheng48459ac22014-08-26 00:46:4112343 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1212344 TestCompletionCallback callback;
12345
12346 int rv = trans.Start(&request, callback.callback(), BoundNetLog());
12347 EXPECT_EQ(ERR_IO_PENDING, rv);
12348 callback.WaitForResult();
12349
12350 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212351 ASSERT_TRUE(response);
12352 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1212353 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12354
12355 // The transaction and HttpRequestInfo are deleted.
12356 }
12357
12358 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5512359 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1212360
12361 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4112362 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1212363}
12364
[email protected]76a505b2010-08-25 06:23:0012365// Test a basic GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0212366TEST_P(HttpNetworkTransactionTest, ProxyGet) {
rdsmith82957ad2015-09-16 19:42:0312367 session_deps_.proxy_service =
12368 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112369 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712370 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912371 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012372
[email protected]76a505b2010-08-25 06:23:0012373 HttpRequestInfo request;
12374 request.method = "GET";
bncce36dca22015-04-21 22:11:2312375 request.url = GURL("http://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012376
12377 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2312378 MockWrite(
12379 "GET http://www.example.org/ HTTP/1.1\r\n"
12380 "Host: www.example.org\r\n"
12381 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012382 };
12383
12384 MockRead data_reads1[] = {
12385 MockRead("HTTP/1.1 200 OK\r\n"),
12386 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12387 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612388 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012389 };
12390
12391 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12392 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712393 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0012394
[email protected]49639fa2011-12-20 23:22:4112395 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012396
danakj1fd259a02016-04-16 03:17:0912397 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012398 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
ryansturm49a8cb12016-06-15 16:51:0912399 BeforeHeadersSentHandler headers_handler;
12400 trans->SetBeforeHeadersSentCallback(
12401 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12402 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012403
[email protected]49639fa2011-12-20 23:22:4112404 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0012405 EXPECT_EQ(ERR_IO_PENDING, rv);
12406
12407 rv = callback1.WaitForResult();
12408 EXPECT_EQ(OK, rv);
12409
12410 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212411 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012412
12413 EXPECT_TRUE(response->headers->IsKeepAlive());
12414 EXPECT_EQ(200, response->headers->response_code());
12415 EXPECT_EQ(100, response->headers->GetContentLength());
12416 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1512417 EXPECT_TRUE(
12418 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
ryansturm49a8cb12016-06-15 16:51:0912419 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12420 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12421 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0012422 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2012423
12424 LoadTimingInfo load_timing_info;
12425 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12426 TestLoadTimingNotReusedWithPac(load_timing_info,
12427 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0012428}
12429
12430// Test a basic HTTPS GET request through a proxy.
[email protected]23e482282013-06-14 16:08:0212431TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
rdsmith82957ad2015-09-16 19:42:0312432 session_deps_.proxy_service =
12433 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112434 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712435 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912436 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012437
[email protected]76a505b2010-08-25 06:23:0012438 HttpRequestInfo request;
12439 request.method = "GET";
bncce36dca22015-04-21 22:11:2312440 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012441
12442 // Since we have proxy, should try to establish tunnel.
12443 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712444 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12445 "Host: www.example.org:443\r\n"
12446 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012447
rsleevidb16bb02015-11-12 23:47:1712448 MockWrite("GET / HTTP/1.1\r\n"
12449 "Host: www.example.org\r\n"
12450 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012451 };
12452
12453 MockRead data_reads1[] = {
12454 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12455
12456 MockRead("HTTP/1.1 200 OK\r\n"),
12457 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12458 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612459 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0012460 };
12461
12462 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12463 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712464 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612465 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712466 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012467
[email protected]49639fa2011-12-20 23:22:4112468 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012469
danakj1fd259a02016-04-16 03:17:0912470 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012471 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
ryansturm49a8cb12016-06-15 16:51:0912472 BeforeHeadersSentHandler headers_handler;
12473 trans->SetBeforeHeadersSentCallback(
12474 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
12475 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5012476
[email protected]49639fa2011-12-20 23:22:4112477 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0012478 EXPECT_EQ(ERR_IO_PENDING, rv);
12479
12480 rv = callback1.WaitForResult();
12481 EXPECT_EQ(OK, rv);
mmenke43758e62015-05-04 21:09:4612482 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012483 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012484 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012485 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0012486 NetLog::PHASE_NONE);
12487 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012488 entries, pos,
[email protected]76a505b2010-08-25 06:23:0012489 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12490 NetLog::PHASE_NONE);
12491
12492 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212493 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0012494
12495 EXPECT_TRUE(response->headers->IsKeepAlive());
12496 EXPECT_EQ(200, response->headers->response_code());
12497 EXPECT_EQ(100, response->headers->GetContentLength());
12498 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12499 EXPECT_TRUE(response->was_fetched_via_proxy);
[email protected]d8fc4722014-06-13 13:17:1512500 EXPECT_TRUE(
12501 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
ryansturm49a8cb12016-06-15 16:51:0912502 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
12503 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
12504 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2012505
12506 LoadTimingInfo load_timing_info;
12507 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12508 TestLoadTimingNotReusedWithPac(load_timing_info,
12509 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0012510}
12511
rsleevidb16bb02015-11-12 23:47:1712512// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
12513// literal host.
12514TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
12515 session_deps_.proxy_service =
12516 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
12517 BoundTestNetLog log;
12518 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912519 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1712520
12521 HttpRequestInfo request;
12522 request.method = "GET";
12523 request.url = GURL("https://[::1]:443/");
12524
12525 // Since we have proxy, should try to establish tunnel.
12526 MockWrite data_writes1[] = {
12527 MockWrite("CONNECT [::1]:443 HTTP/1.1\r\n"
12528 "Host: [::1]:443\r\n"
12529 "Proxy-Connection: keep-alive\r\n\r\n"),
12530
12531 MockWrite("GET / HTTP/1.1\r\n"
12532 "Host: [::1]\r\n"
12533 "Connection: keep-alive\r\n\r\n"),
12534 };
12535
12536 MockRead data_reads1[] = {
12537 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
12538
12539 MockRead("HTTP/1.1 200 OK\r\n"),
12540 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
12541 MockRead("Content-Length: 100\r\n\r\n"),
12542 MockRead(SYNCHRONOUS, OK),
12543 };
12544
12545 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12546 data_writes1, arraysize(data_writes1));
12547 session_deps_.socket_factory->AddSocketDataProvider(&data1);
12548 SSLSocketDataProvider ssl(ASYNC, OK);
12549 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12550
12551 TestCompletionCallback callback1;
12552
danakj1fd259a02016-04-16 03:17:0912553 std::unique_ptr<HttpTransaction> trans(
rsleevidb16bb02015-11-12 23:47:1712554 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12555
12556 int rv = trans->Start(&request, callback1.callback(), log.bound());
12557 EXPECT_EQ(ERR_IO_PENDING, rv);
12558
12559 rv = callback1.WaitForResult();
12560 EXPECT_EQ(OK, rv);
12561 TestNetLogEntry::List entries;
12562 log.GetEntries(&entries);
12563 size_t pos = ExpectLogContainsSomewhere(
12564 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
12565 NetLog::PHASE_NONE);
12566 ExpectLogContainsSomewhere(
12567 entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12568 NetLog::PHASE_NONE);
12569
12570 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212571 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1712572
12573 EXPECT_TRUE(response->headers->IsKeepAlive());
12574 EXPECT_EQ(200, response->headers->response_code());
12575 EXPECT_EQ(100, response->headers->GetContentLength());
12576 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
12577 EXPECT_TRUE(response->was_fetched_via_proxy);
12578 EXPECT_TRUE(
12579 response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
12580
12581 LoadTimingInfo load_timing_info;
12582 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12583 TestLoadTimingNotReusedWithPac(load_timing_info,
12584 CONNECT_TIMING_HAS_SSL_TIMES);
12585}
12586
[email protected]76a505b2010-08-25 06:23:0012587// Test a basic HTTPS GET request through a proxy, but the server hangs up
12588// while establishing the tunnel.
[email protected]23e482282013-06-14 16:08:0212589TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
rdsmith82957ad2015-09-16 19:42:0312590 session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70");
vishal.b62985ca92015-04-17 08:45:5112591 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712592 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0912593 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0012594
[email protected]76a505b2010-08-25 06:23:0012595 HttpRequestInfo request;
12596 request.method = "GET";
bncce36dca22015-04-21 22:11:2312597 request.url = GURL("https://www.example.org/");
[email protected]76a505b2010-08-25 06:23:0012598
12599 // Since we have proxy, should try to establish tunnel.
12600 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1712601 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
12602 "Host: www.example.org:443\r\n"
12603 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012604
rsleevidb16bb02015-11-12 23:47:1712605 MockWrite("GET / HTTP/1.1\r\n"
12606 "Host: www.example.org\r\n"
12607 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0012608 };
12609
12610 MockRead data_reads1[] = {
[email protected]8ddf8322012-02-23 18:08:0612611 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]76a505b2010-08-25 06:23:0012612 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0612613 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0012614 };
12615
12616 StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
12617 data_writes1, arraysize(data_writes1));
[email protected]bb88e1d32013-05-03 23:11:0712618 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0612619 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0712620 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0012621
[email protected]49639fa2011-12-20 23:22:4112622 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0012623
danakj1fd259a02016-04-16 03:17:0912624 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012625 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]0b0bf032010-09-21 18:08:5012626
[email protected]49639fa2011-12-20 23:22:4112627 int rv = trans->Start(&request, callback1.callback(), log.bound());
[email protected]76a505b2010-08-25 06:23:0012628 EXPECT_EQ(ERR_IO_PENDING, rv);
12629
12630 rv = callback1.WaitForResult();
12631 EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
mmenke43758e62015-05-04 21:09:4612632 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4012633 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0012634 size_t pos = ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012635 entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
[email protected]76a505b2010-08-25 06:23:0012636 NetLog::PHASE_NONE);
12637 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4012638 entries, pos,
[email protected]76a505b2010-08-25 06:23:0012639 NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
12640 NetLog::PHASE_NONE);
12641}
12642
[email protected]749eefa82010-09-13 22:14:0312643// Test for crbug.com/55424.
[email protected]23e482282013-06-14 16:08:0212644TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
danakj1fd259a02016-04-16 03:17:0912645 std::unique_ptr<SpdySerializedFrame> req(
bnc38dcd392016-02-09 23:19:4912646 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rch8e6c6c42015-05-01 14:05:1312647 MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
[email protected]749eefa82010-09-13 22:14:0312648
danakj1fd259a02016-04-16 03:17:0912649 std::unique_ptr<SpdySerializedFrame> resp(
bncb03b1092016-04-06 11:19:5512650 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0912651 std::unique_ptr<SpdySerializedFrame> data(
bncb03b1092016-04-06 11:19:5512652 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0312653 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1312654 CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0312655 };
12656
rch8e6c6c42015-05-01 14:05:1312657 SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes,
12658 arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0712659 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0312660
[email protected]8ddf8322012-02-23 18:08:0612661 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3812662 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0712663 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0312664
danakj1fd259a02016-04-16 03:17:0912665 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0312666
12667 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2312668 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012669 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
[email protected]314b03992014-04-01 01:28:5312670 PRIVACY_MODE_DISABLED);
[email protected]795cbf82013-07-22 09:37:2712671 base::WeakPtr<SpdySession> spdy_session =
mmenkee65e7af2015-10-13 17:16:4212672 CreateInsecureSpdySession(session.get(), key, BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0312673
12674 HttpRequestInfo request;
12675 request.method = "GET";
bncce36dca22015-04-21 22:11:2312676 request.url = GURL("https://www.example.org/");
[email protected]749eefa82010-09-13 22:14:0312677 request.load_flags = 0;
12678
12679 // This is the important line that marks this as a preconnect.
12680 request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
12681
danakj1fd259a02016-04-16 03:17:0912682 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012683 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]749eefa82010-09-13 22:14:0312684
[email protected]41d64e82013-07-03 22:44:2612685 TestCompletionCallback callback;
[email protected]49639fa2011-12-20 23:22:4112686 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
[email protected]749eefa82010-09-13 22:14:0312687 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4112688 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]749eefa82010-09-13 22:14:0312689}
12690
[email protected]73b8dd222010-11-11 19:55:2412691// Given a net error, cause that error to be returned from the first Write()
12692// call and verify that the HttpTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0212693void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0712694 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2912695 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712696 request_info.url = GURL("https://www.example.com/");
12697 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912698 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712699
[email protected]8ddf8322012-02-23 18:08:0612700 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2912701 MockWrite data_writes[] = {
12702 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2412703 };
ttuttle859dc7a2015-04-23 19:42:2912704 StaticSocketDataProvider data(NULL, 0, data_writes, arraysize(data_writes));
[email protected]bb88e1d32013-05-03 23:11:0712705 session_deps_.socket_factory->AddSocketDataProvider(&data);
12706 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2412707
danakj1fd259a02016-04-16 03:17:0912708 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12709 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012710 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]73b8dd222010-11-11 19:55:2412711
[email protected]49639fa2011-12-20 23:22:4112712 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912713 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12714 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2412715 rv = callback.WaitForResult();
12716 ASSERT_EQ(error, rv);
12717}
12718
[email protected]23e482282013-06-14 16:08:0212719TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2412720 // Just check a grab bag of cert errors.
12721 static const int kErrors[] = {
12722 ERR_CERT_COMMON_NAME_INVALID,
12723 ERR_CERT_AUTHORITY_INVALID,
12724 ERR_CERT_DATE_INVALID,
12725 };
12726 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0612727 CheckErrorIsPassedBack(kErrors[i], ASYNC);
12728 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2412729 }
12730}
12731
[email protected]bd0b6772011-01-11 19:59:3012732// Ensure that a client certificate is removed from the SSL client auth
12733// cache when:
12734// 1) No proxy is involved.
12735// 2) TLS False Start is disabled.
12736// 3) The initial TLS handshake requests a client certificate.
12737// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0212738TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2312739 ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2912740 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712741 request_info.url = GURL("https://www.example.com/");
12742 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912743 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712744
[email protected]bd0b6772011-01-11 19:59:3012745 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112746 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3012747
12748 // [ssl_]data1 contains the data for the first SSL handshake. When a
12749 // CertificateRequest is received for the first time, the handshake will
12750 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2912751 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3012752 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712753 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912754 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712755 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3012756
12757 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
12758 // False Start is not being used, the result of the SSL handshake will be
12759 // returned as part of the SSLClientSocket::Connect() call. This test
12760 // matches the result of a server sending a handshake_failure alert,
12761 // rather than a Finished message, because it requires a client
12762 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2912763 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3012764 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712765 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912766 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712767 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3012768
12769 // [ssl_]data3 contains the data for the third SSL handshake. When a
12770 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4212771 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
12772 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3012773 // of the HttpNetworkTransaction. Because this test failure is due to
12774 // requiring a client certificate, this fallback handshake should also
12775 // fail.
ttuttle859dc7a2015-04-23 19:42:2912776 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3012777 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712778 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912779 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712780 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3012781
[email protected]80c75f682012-05-26 16:22:1712782 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
12783 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4212784 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
12785 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1712786 // of the HttpNetworkTransaction. Because this test failure is due to
12787 // requiring a client certificate, this fallback handshake should also
12788 // fail.
ttuttle859dc7a2015-04-23 19:42:2912789 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1712790 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712791 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2912792 StaticSocketDataProvider data4(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712793 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1712794
danakj1fd259a02016-04-16 03:17:0912795 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12796 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012797 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3012798
[email protected]bd0b6772011-01-11 19:59:3012799 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4112800 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912801 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12802 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012803
12804 // Complete the SSL handshake, which should abort due to requiring a
12805 // client certificate.
12806 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912807 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3012808
12809 // Indicate that no certificate should be supplied. From the perspective
12810 // of SSLClientCertCache, NULL is just as meaningful as a real
12811 // certificate, so this is the same as supply a
12812 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5412813 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912814 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012815
12816 // Ensure the certificate was added to the client auth cache before
12817 // allowing the connection to continue restarting.
12818 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412819 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112820 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412821 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5212822 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3012823
12824 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1712825 // then consume ssl_data3 and ssl_data4, both of which should also fail.
12826 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3012827 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912828 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3012829
12830 // Ensure that the client certificate is removed from the cache on a
12831 // handshake failure.
[email protected]791879c2013-12-17 07:22:4112832 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412833 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3012834}
12835
12836// Ensure that a client certificate is removed from the SSL client auth
12837// cache when:
12838// 1) No proxy is involved.
12839// 2) TLS False Start is enabled.
12840// 3) The initial TLS handshake requests a client certificate.
12841// 4) The client supplies an invalid/unacceptable certificate.
[email protected]23e482282013-06-14 16:08:0212842TEST_P(HttpNetworkTransactionTest,
[email protected]448d4ca52012-03-04 04:12:2312843 ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2912844 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2712845 request_info.url = GURL("https://www.example.com/");
12846 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912847 request_info.load_flags = LOAD_NORMAL;
[email protected]cb9bf6ca2011-01-28 13:15:2712848
[email protected]bd0b6772011-01-11 19:59:3012849 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112850 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3012851
12852 // When TLS False Start is used, SSLClientSocket::Connect() calls will
12853 // return successfully after reading up to the peer's Certificate message.
12854 // This is to allow the caller to call SSLClientSocket::Write(), which can
12855 // enqueue application data to be sent in the same packet as the
12856 // ChangeCipherSpec and Finished messages.
12857 // The actual handshake will be finished when SSLClientSocket::Read() is
12858 // called, which expects to process the peer's ChangeCipherSpec and
12859 // Finished messages. If there was an error negotiating with the peer,
12860 // such as due to the peer requiring a client certificate when none was
12861 // supplied, the alert sent by the peer won't be processed until Read() is
12862 // called.
12863
12864 // Like the non-False Start case, when a client certificate is requested by
12865 // the peer, the handshake is aborted during the Connect() call.
12866 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2912867 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3012868 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712869 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912870 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712871 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3012872
12873 // When a client certificate is supplied, Connect() will not be aborted
12874 // when the peer requests the certificate. Instead, the handshake will
12875 // artificially succeed, allowing the caller to write the HTTP request to
12876 // the socket. The handshake messages are not processed until Read() is
12877 // called, which then detects that the handshake was aborted, due to the
12878 // peer sending a handshake_failure because it requires a client
12879 // certificate.
ttuttle859dc7a2015-04-23 19:42:2912880 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3012881 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712882 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912883 MockRead data2_reads[] = {
12884 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3012885 };
ttuttle859dc7a2015-04-23 19:42:2912886 StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712887 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3012888
12889 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1712890 // the data for the SSL handshake once the TLSv1.1 connection falls back to
12891 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2912892 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3012893 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712894 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912895 StaticSocketDataProvider data3(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712896 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3012897
[email protected]80c75f682012-05-26 16:22:1712898 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
12899 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2912900 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1712901 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712902 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
ttuttle859dc7a2015-04-23 19:42:2912903 StaticSocketDataProvider data4(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712904 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1712905
[email protected]7799de12013-05-30 05:52:5112906 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2912907 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5112908 ssl_data5.cert_request_info = cert_request.get();
12909 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
ttuttle859dc7a2015-04-23 19:42:2912910 StaticSocketDataProvider data5(data2_reads, arraysize(data2_reads), NULL, 0);
[email protected]7799de12013-05-30 05:52:5112911 session_deps_.socket_factory->AddSocketDataProvider(&data5);
12912
danakj1fd259a02016-04-16 03:17:0912913 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12914 std::unique_ptr<HttpTransaction> trans(
[email protected]90499482013-06-01 00:39:5012915 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]bd0b6772011-01-11 19:59:3012916
[email protected]bd0b6772011-01-11 19:59:3012917 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4112918 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2912919 int rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
12920 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012921
12922 // Complete the SSL handshake, which should abort due to requiring a
12923 // client certificate.
12924 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912925 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]bd0b6772011-01-11 19:59:3012926
12927 // Indicate that no certificate should be supplied. From the perspective
12928 // of SSLClientCertCache, NULL is just as meaningful as a real
12929 // certificate, so this is the same as supply a
12930 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5412931 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2912932 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]bd0b6772011-01-11 19:59:3012933
12934 // Ensure the certificate was added to the client auth cache before
12935 // allowing the connection to continue restarting.
12936 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5412937 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4112938 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412939 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5212940 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3012941
[email protected]bd0b6772011-01-11 19:59:3012942 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1712943 // then consume ssl_data3 and ssl_data4, both of which should also fail.
12944 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3012945 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2912946 ASSERT_EQ(ERR_SSL_PROTOCOL_ERROR, rv);
[email protected]bd0b6772011-01-11 19:59:3012947
12948 // Ensure that the client certificate is removed from the cache on a
12949 // handshake failure.
[email protected]791879c2013-12-17 07:22:4112950 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5412951 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3012952}
12953
[email protected]8c405132011-01-11 22:03:1812954// Ensure that a client certificate is removed from the SSL client auth
12955// cache when:
12956// 1) An HTTPS proxy is involved.
12957// 3) The HTTPS proxy requests a client certificate.
12958// 4) The client supplies an invalid/unacceptable certificate for the
12959// proxy.
12960// The test is repeated twice, first for connecting to an HTTPS endpoint,
12961// then for connecting to an HTTP endpoint.
[email protected]23e482282013-06-14 16:08:0212962TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
rdsmith82957ad2015-09-16 19:42:0312963 session_deps_.proxy_service = ProxyService::CreateFixed("https://proxy:70");
vishal.b62985ca92015-04-17 08:45:5112964 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0712965 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1812966
12967 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4112968 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1812969
12970 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
12971 // [ssl_]data[1-3]. Rather than represending the endpoint
12972 // (www.example.com:443), they represent failures with the HTTPS proxy
12973 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2912974 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1812975 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712976 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
ttuttle859dc7a2015-04-23 19:42:2912977 StaticSocketDataProvider data1(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712978 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1812979
ttuttle859dc7a2015-04-23 19:42:2912980 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1812981 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712982 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2912983 StaticSocketDataProvider data2(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712984 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1812985
[email protected]80c75f682012-05-26 16:22:1712986 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
12987#if 0
ttuttle859dc7a2015-04-23 19:42:2912988 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1812989 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0712990 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
ttuttle859dc7a2015-04-23 19:42:2912991 StaticSocketDataProvider data3(NULL, 0, NULL, 0);
[email protected]bb88e1d32013-05-03 23:11:0712992 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1712993#endif
[email protected]8c405132011-01-11 22:03:1812994
ttuttle859dc7a2015-04-23 19:42:2912995 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1812996 requests[0].url = GURL("https://www.example.com/");
12997 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2912998 requests[0].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1812999
13000 requests[1].url = GURL("http://www.example.com/");
13001 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2913002 requests[1].load_flags = LOAD_NORMAL;
[email protected]8c405132011-01-11 22:03:1813003
13004 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0713005 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0913006 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13007 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5013008 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]8c405132011-01-11 22:03:1813009
13010 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4113011 TestCompletionCallback callback;
ttuttle859dc7a2015-04-23 19:42:2913012 int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog());
13013 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1813014
13015 // Complete the SSL handshake, which should abort due to requiring a
13016 // client certificate.
13017 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2913018 ASSERT_EQ(ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
[email protected]8c405132011-01-11 22:03:1813019
13020 // Indicate that no certificate should be supplied. From the perspective
13021 // of SSLClientCertCache, NULL is just as meaningful as a real
13022 // certificate, so this is the same as supply a
13023 // legitimate-but-unacceptable certificate.
svaldez7872fd02015-11-19 21:10:5413024 rv = trans->RestartWithCertificate(NULL, NULL, callback.callback());
ttuttle859dc7a2015-04-23 19:42:2913025 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]8c405132011-01-11 22:03:1813026
13027 // Ensure the certificate was added to the client auth cache before
13028 // allowing the connection to continue restarting.
13029 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5413030 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4113031 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413032 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5213033 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1813034 // Ensure the certificate was NOT cached for the endpoint. This only
13035 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4113036 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413037 HostPortPair("www.example.com", 443), &client_cert,
13038 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813039
13040 // Restart the handshake. This will consume ssl_data2, which fails, and
13041 // then consume ssl_data3, which should also fail. The result code is
13042 // checked against what ssl_data3 should return.
13043 rv = callback.WaitForResult();
ttuttle859dc7a2015-04-23 19:42:2913044 ASSERT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
[email protected]8c405132011-01-11 22:03:1813045
13046 // Now that the new handshake has failed, ensure that the client
13047 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4113048 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413049 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4113050 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5413051 HostPortPair("www.example.com", 443), &client_cert,
13052 &client_private_key));
[email protected]8c405132011-01-11 22:03:1813053 }
13054}
13055
mmenke5c642132015-06-02 16:05:1313056TEST_P(HttpNetworkTransactionTest, UseIPConnectionPooling) {
bncf33fb31b2016-01-29 15:22:2613057 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]e3ceb682011-06-28 23:55:4613058
13059 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0713060 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0913061 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2613062 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
13063 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4613064
[email protected]8ddf8322012-02-23 18:08:0613065 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813066 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0713067 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4613068
danakj1fd259a02016-04-16 03:17:0913069 std::unique_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4913070 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813071 spdy_util_.UpdateWithStreamDestruction(1);
danakj1fd259a02016-04-16 03:17:0913072 std::unique_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4913073 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613074 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313075 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613076 };
danakj1fd259a02016-04-16 03:17:0913077 std::unique_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0213078 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913079 std::unique_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0213080 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0913081 std::unique_ptr<SpdySerializedFrame> host2_resp(
[email protected]23e482282013-06-14 16:08:0213082 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0913083 std::unique_ptr<SpdySerializedFrame> host2_resp_body(
[email protected]23e482282013-06-14 16:08:0213084 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613085 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1313086 CreateMockRead(*host1_resp, 1),
13087 CreateMockRead(*host1_resp_body, 2),
13088 CreateMockRead(*host2_resp, 4),
13089 CreateMockRead(*host2_resp_body, 5),
13090 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613091 };
13092
eroman36d84e54432016-03-17 03:23:0213093 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213094 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313095 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13096 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713097 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613098
[email protected]aa22b242011-11-16 18:58:2913099 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613100 HttpRequestInfo request1;
13101 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313102 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613103 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013104 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613105
[email protected]49639fa2011-12-20 23:22:4113106 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4613107 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4113108 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4613109
13110 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213111 ASSERT_TRUE(response);
13112 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213113 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613114
13115 std::string response_data;
13116 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
13117 EXPECT_EQ("hello!", response_data);
13118
13119 // Preload www.gmail.com into HostCache.
13120 HostPortPair host_port("www.gmail.com", 443);
[email protected]5109c1952013-08-20 18:44:1013121 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4613122 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1013123 rv = session_deps_.host_resolver->Resolve(resolve_info,
13124 DEFAULT_PRIORITY,
13125 &ignored,
13126 callback.callback(),
13127 NULL,
13128 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4713129 EXPECT_EQ(ERR_IO_PENDING, rv);
13130 rv = callback.WaitForResult();
13131 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4613132
13133 HttpRequestInfo request2;
13134 request2.method = "GET";
13135 request2.url = GURL("https://www.gmail.com/");
13136 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013137 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613138
[email protected]49639fa2011-12-20 23:22:4113139 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4613140 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4113141 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4613142
13143 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213144 ASSERT_TRUE(response);
13145 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213146 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613147 EXPECT_TRUE(response->was_fetched_via_spdy);
13148 EXPECT_TRUE(response->was_npn_negotiated);
13149 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
13150 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613151}
13152
[email protected]23e482282013-06-14 16:08:0213153TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
bncf33fb31b2016-01-29 15:22:2613154 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]d2b5f092012-06-08 23:55:0213155
13156 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
[email protected]bb88e1d32013-05-03 23:11:0713157 session_deps_.host_resolver.reset(new MockCachingHostResolver());
danakj1fd259a02016-04-16 03:17:0913158 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0213159 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
13160 pool_peer.DisableDomainAuthenticationVerification();
13161
13162 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813163 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0713164 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]d2b5f092012-06-08 23:55:0213165
danakj1fd259a02016-04-16 03:17:0913166 std::unique_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4913167 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813168 spdy_util_.UpdateWithStreamDestruction(1);
danakj1fd259a02016-04-16 03:17:0913169 std::unique_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4913170 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0213171 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313172 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0213173 };
danakj1fd259a02016-04-16 03:17:0913174 std::unique_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0213175 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913176 std::unique_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0213177 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0913178 std::unique_ptr<SpdySerializedFrame> host2_resp(
[email protected]23e482282013-06-14 16:08:0213179 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0913180 std::unique_ptr<SpdySerializedFrame> host2_resp_body(
[email protected]23e482282013-06-14 16:08:0213181 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0213182 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1313183 CreateMockRead(*host1_resp, 1),
13184 CreateMockRead(*host1_resp_body, 2),
13185 CreateMockRead(*host2_resp, 4),
13186 CreateMockRead(*host2_resp_body, 5),
13187 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0213188 };
13189
eroman36d84e54432016-03-17 03:23:0213190 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213191 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313192 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13193 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713194 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0213195
13196 TestCompletionCallback callback;
13197 HttpRequestInfo request1;
13198 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313199 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0213200 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013201 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213202
13203 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
13204 EXPECT_EQ(ERR_IO_PENDING, rv);
13205 EXPECT_EQ(OK, callback.WaitForResult());
13206
13207 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213208 ASSERT_TRUE(response);
13209 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213210 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213211
13212 std::string response_data;
13213 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
13214 EXPECT_EQ("hello!", response_data);
13215
13216 HttpRequestInfo request2;
13217 request2.method = "GET";
13218 request2.url = GURL("https://www.gmail.com/");
13219 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013220 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0213221
13222 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
13223 EXPECT_EQ(ERR_IO_PENDING, rv);
13224 EXPECT_EQ(OK, callback.WaitForResult());
13225
13226 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213227 ASSERT_TRUE(response);
13228 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213229 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0213230 EXPECT_TRUE(response->was_fetched_via_spdy);
13231 EXPECT_TRUE(response->was_npn_negotiated);
13232 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
13233 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0213234}
13235
ttuttle859dc7a2015-04-23 19:42:2913236class OneTimeCachingHostResolver : public HostResolver {
[email protected]e3ceb682011-06-28 23:55:4613237 public:
13238 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
13239 : host_port_(host_port) {}
dchengb03027d2014-10-21 12:00:2013240 ~OneTimeCachingHostResolver() override {}
[email protected]e3ceb682011-06-28 23:55:4613241
13242 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
13243
13244 // HostResolver methods:
dchengb03027d2014-10-21 12:00:2013245 int Resolve(const RequestInfo& info,
13246 RequestPriority priority,
13247 AddressList* addresses,
13248 const CompletionCallback& callback,
13249 RequestHandle* out_req,
13250 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4013251 return host_resolver_.Resolve(
[email protected]5109c1952013-08-20 18:44:1013252 info, priority, addresses, callback, out_req, net_log);
[email protected]95a214c2011-08-04 21:50:4013253 }
13254
dchengb03027d2014-10-21 12:00:2013255 int ResolveFromCache(const RequestInfo& info,
13256 AddressList* addresses,
13257 const BoundNetLog& net_log) override {
[email protected]95a214c2011-08-04 21:50:4013258 int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
13259 if (rv == OK && info.host_port_pair().Equals(host_port_))
[email protected]98e1cd012011-11-08 15:33:0913260 host_resolver_.GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4613261 return rv;
13262 }
13263
dchengb03027d2014-10-21 12:00:2013264 void CancelRequest(RequestHandle req) override {
[email protected]e3ceb682011-06-28 23:55:4613265 host_resolver_.CancelRequest(req);
13266 }
13267
[email protected]46da33be2011-07-19 21:58:0413268 MockCachingHostResolver* GetMockHostResolver() {
13269 return &host_resolver_;
13270 }
13271
[email protected]e3ceb682011-06-28 23:55:4613272 private:
13273 MockCachingHostResolver host_resolver_;
13274 const HostPortPair host_port_;
13275};
13276
mmenke5c642132015-06-02 16:05:1313277TEST_P(HttpNetworkTransactionTest,
13278 UseIPConnectionPoolingWithHostCacheExpiration) {
bncf33fb31b2016-01-29 15:22:2613279 session_deps_.enable_alternative_service_with_different_host = false;
[email protected]e3ceb682011-06-28 23:55:4613280
13281 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
[email protected]e3ceb682011-06-28 23:55:4613282 OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
[email protected]c6bf8152012-12-02 07:43:3413283 HttpNetworkSession::Params params =
[email protected]bb88e1d32013-05-03 23:11:0713284 SpdySessionDependencies::CreateSessionParams(&session_deps_);
[email protected]e3ceb682011-06-28 23:55:4613285 params.host_resolver = &host_resolver;
danakj1fd259a02016-04-16 03:17:0913286 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]b9ec6882011-07-01 07:40:2613287 SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
13288 pool_peer.DisableDomainAuthenticationVerification();
[email protected]e3ceb682011-06-28 23:55:4613289
[email protected]8ddf8322012-02-23 18:08:0613290 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813291 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0713292 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e3ceb682011-06-28 23:55:4613293
danakj1fd259a02016-04-16 03:17:0913294 std::unique_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4913295 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813296 spdy_util_.UpdateWithStreamDestruction(1);
danakj1fd259a02016-04-16 03:17:0913297 std::unique_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4913298 spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4613299 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313300 CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4613301 };
danakj1fd259a02016-04-16 03:17:0913302 std::unique_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0213303 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913304 std::unique_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0213305 spdy_util_.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0913306 std::unique_ptr<SpdySerializedFrame> host2_resp(
[email protected]23e482282013-06-14 16:08:0213307 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0913308 std::unique_ptr<SpdySerializedFrame> host2_resp_body(
[email protected]23e482282013-06-14 16:08:0213309 spdy_util_.ConstructSpdyBodyFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4613310 MockRead spdy_reads[] = {
rch8e6c6c42015-05-01 14:05:1313311 CreateMockRead(*host1_resp, 1),
13312 CreateMockRead(*host1_resp_body, 2),
13313 CreateMockRead(*host2_resp, 4),
13314 CreateMockRead(*host2_resp_body, 5),
13315 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4613316 };
13317
eroman36d84e54432016-03-17 03:23:0213318 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0213319 MockConnect connect(ASYNC, OK, peer_addr);
rch8e6c6c42015-05-01 14:05:1313320 SequencedSocketData spdy_data(connect, spdy_reads, arraysize(spdy_reads),
13321 spdy_writes, arraysize(spdy_writes));
[email protected]bb88e1d32013-05-03 23:11:0713322 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4613323
[email protected]aa22b242011-11-16 18:58:2913324 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4613325 HttpRequestInfo request1;
13326 request1.method = "GET";
bncce36dca22015-04-21 22:11:2313327 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4613328 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013329 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613330
[email protected]49639fa2011-12-20 23:22:4113331 int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4613332 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4113333 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4613334
13335 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213336 ASSERT_TRUE(response);
13337 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213338 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613339
13340 std::string response_data;
13341 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
13342 EXPECT_EQ("hello!", response_data);
13343
13344 // Preload cache entries into HostCache.
[email protected]5109c1952013-08-20 18:44:1013345 HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
[email protected]e3ceb682011-06-28 23:55:4613346 AddressList ignored;
[email protected]5109c1952013-08-20 18:44:1013347 rv = host_resolver.Resolve(resolve_info,
13348 DEFAULT_PRIORITY,
13349 &ignored,
13350 callback.callback(),
13351 NULL,
13352 BoundNetLog());
[email protected]6e78dfb2011-07-28 21:34:4713353 EXPECT_EQ(ERR_IO_PENDING, rv);
13354 rv = callback.WaitForResult();
13355 EXPECT_EQ(OK, rv);
[email protected]e3ceb682011-06-28 23:55:4613356
13357 HttpRequestInfo request2;
13358 request2.method = "GET";
13359 request2.url = GURL("https://www.gmail.com/");
13360 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013361 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4613362
[email protected]49639fa2011-12-20 23:22:4113363 rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
[email protected]e3ceb682011-06-28 23:55:4613364 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]49639fa2011-12-20 23:22:4113365 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]e3ceb682011-06-28 23:55:4613366
13367 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213368 ASSERT_TRUE(response);
13369 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213370 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4613371 EXPECT_TRUE(response->was_fetched_via_spdy);
13372 EXPECT_TRUE(response->was_npn_negotiated);
13373 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
13374 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4613375}
13376
[email protected]23e482282013-06-14 16:08:0213377TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2313378 const std::string https_url = "https://www.example.org:8080/";
13379 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413380
13381 // SPDY GET for HTTPS URL
danakj1fd259a02016-04-16 03:17:0913382 std::unique_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4913383 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0413384
13385 MockWrite writes1[] = {
13386 CreateMockWrite(*req1, 0),
13387 };
13388
danakj1fd259a02016-04-16 03:17:0913389 std::unique_ptr<SpdySerializedFrame> resp1(
bncb03b1092016-04-06 11:19:5513390 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0913391 std::unique_ptr<SpdySerializedFrame> body1(
bncb03b1092016-04-06 11:19:5513392 spdy_util_.ConstructSpdyBodyFrame(1, true));
mmenkee24011922015-12-17 22:12:5913393 MockRead reads1[] = {CreateMockRead(*resp1, 1), CreateMockRead(*body1, 2),
13394 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0413395
rch8e6c6c42015-05-01 14:05:1313396 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13397 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413398 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713399 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413400
13401 // HTTP GET for the HTTP URL
13402 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1313403 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3413404 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2313405 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3413406 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0413407 };
13408
13409 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1313410 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
13411 MockRead(ASYNC, 2, "hello"),
13412 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0413413 };
13414
rch8e6c6c42015-05-01 14:05:1313415 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
13416 arraysize(writes2));
[email protected]8450d722012-07-02 19:14:0413417
[email protected]8450d722012-07-02 19:14:0413418 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813419 ssl.SetNextProto(GetProtocol());
[email protected]bb88e1d32013-05-03 23:11:0713420 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13421 session_deps_.socket_factory->AddSocketDataProvider(&data1);
13422 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0413423
danakj1fd259a02016-04-16 03:17:0913424 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0413425
13426 // Start the first transaction to set up the SpdySession
13427 HttpRequestInfo request1;
13428 request1.method = "GET";
13429 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413430 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013431 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413432 TestCompletionCallback callback1;
13433 EXPECT_EQ(ERR_IO_PENDING,
13434 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
fdoray92e35a72016-06-10 15:54:5513435 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413436
13437 EXPECT_EQ(OK, callback1.WaitForResult());
13438 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13439
13440 // Now, start the HTTP request
13441 HttpRequestInfo request2;
13442 request2.method = "GET";
13443 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413444 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013445 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413446 TestCompletionCallback callback2;
13447 EXPECT_EQ(ERR_IO_PENDING,
13448 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
fdoray92e35a72016-06-10 15:54:5513449 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0413450
13451 EXPECT_EQ(OK, callback2.WaitForResult());
13452 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
13453}
13454
bnc1b0e36852015-04-28 15:32:5913455class AltSvcCertificateVerificationTest : public HttpNetworkTransactionTest {
13456 public:
13457 void Run(bool pooling, bool valid) {
zhongyi3d4a55e72016-04-22 20:36:4613458 url::SchemeHostPort server(GURL(valid ? "https://mail.example.org:443"
13459 : "https://invalid.example.org:443"));
bnc1b0e36852015-04-28 15:32:5913460 HostPortPair alternative("www.example.org", 443);
13461
13462 base::FilePath certs_dir = GetTestCertsDirectory();
13463 scoped_refptr<X509Certificate> cert(
13464 ImportCertFromFile(certs_dir, "spdy_pooling.pem"));
wezca1070932016-05-26 20:30:5213465 ASSERT_TRUE(cert);
bnc1b0e36852015-04-28 15:32:5913466 bool common_name_fallback_used;
13467 EXPECT_EQ(valid,
zhongyi3d4a55e72016-04-22 20:36:4613468 cert->VerifyNameMatch(server.host(), &common_name_fallback_used));
bnc1b0e36852015-04-28 15:32:5913469 EXPECT_TRUE(
13470 cert->VerifyNameMatch(alternative.host(), &common_name_fallback_used));
13471 SSLSocketDataProvider ssl(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3813472 ssl.SetNextProto(GetProtocol());
bnc1b0e36852015-04-28 15:32:5913473 ssl.cert = cert;
13474 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13475
13476 // If pooling, then start a request to alternative first to create a
13477 // SpdySession.
13478 std::string url0 = "https://www.example.org:443";
zhongyi3d4a55e72016-04-22 20:36:4613479 // Second request to server, which has an alternative service, and could
bnc1b0e36852015-04-28 15:32:5913480 // open a connection to the alternative host or pool to the existing one.
13481 std::string url1("https://");
zhongyi3d4a55e72016-04-22 20:36:4613482 url1.append(server.host());
bnc1b0e36852015-04-28 15:32:5913483 url1.append(":443");
13484
danakj1fd259a02016-04-16 03:17:0913485 std::unique_ptr<SpdySerializedFrame> req0;
13486 std::unique_ptr<SpdySerializedFrame> req1;
13487 std::unique_ptr<SpdySerializedFrame> resp0;
13488 std::unique_ptr<SpdySerializedFrame> body0;
13489 std::unique_ptr<SpdySerializedFrame> resp1;
13490 std::unique_ptr<SpdySerializedFrame> body1;
bnc1b0e36852015-04-28 15:32:5913491 std::vector<MockWrite> writes;
13492 std::vector<MockRead> reads;
13493
13494 if (pooling) {
bnc38dcd392016-02-09 23:19:4913495 req0.reset(spdy_util_.ConstructSpdyGet(url0.c_str(), 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3813496 spdy_util_.UpdateWithStreamDestruction(1);
bnc38dcd392016-02-09 23:19:4913497 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), 3, LOWEST));
bnc1b0e36852015-04-28 15:32:5913498
13499 writes.push_back(CreateMockWrite(*req0, 0));
13500 writes.push_back(CreateMockWrite(*req1, 3));
13501
13502 resp0.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13503 body0.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
13504 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
13505 body1.reset(spdy_util_.ConstructSpdyBodyFrame(3, true));
13506
13507 reads.push_back(CreateMockRead(*resp0, 1));
13508 reads.push_back(CreateMockRead(*body0, 2));
13509 reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, 4));
13510 reads.push_back(CreateMockRead(*resp1, 5));
13511 reads.push_back(CreateMockRead(*body1, 6));
13512 reads.push_back(MockRead(ASYNC, OK, 7));
13513 } else {
bnc38dcd392016-02-09 23:19:4913514 req1.reset(spdy_util_.ConstructSpdyGet(url1.c_str(), 1, LOWEST));
bnc1b0e36852015-04-28 15:32:5913515
13516 writes.push_back(CreateMockWrite(*req1, 0));
13517
13518 resp1.reset(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
13519 body1.reset(spdy_util_.ConstructSpdyBodyFrame(1, true));
13520
13521 reads.push_back(CreateMockRead(*resp1, 1));
13522 reads.push_back(CreateMockRead(*body1, 2));
13523 reads.push_back(MockRead(ASYNC, OK, 3));
13524 }
13525
davidben5f8b6bc2015-11-25 03:19:5413526 SequencedSocketData data(reads.data(), reads.size(), writes.data(),
13527 writes.size());
bnc1b0e36852015-04-28 15:32:5913528 session_deps_.socket_factory->AddSocketDataProvider(&data);
13529
zhongyi3d4a55e72016-04-22 20:36:4613530 // Connection to the server fails.
bnc1b0e36852015-04-28 15:32:5913531 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
13532 StaticSocketDataProvider data_refused;
13533 data_refused.set_connect_data(mock_connect);
13534 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13535
bncf33fb31b2016-01-29 15:22:2613536 session_deps_.enable_alternative_service_with_different_host = true;
danakj1fd259a02016-04-16 03:17:0913537 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4013538 HttpServerProperties* http_server_properties =
bnc1b0e36852015-04-28 15:32:5913539 session->http_server_properties();
13540 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813541 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213542 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613543 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013544 expiration);
bnc1b0e36852015-04-28 15:32:5913545
13546 // First request to alternative.
13547 if (pooling) {
danakj1fd259a02016-04-16 03:17:0913548 std::unique_ptr<HttpTransaction> trans0(
bnc1b0e36852015-04-28 15:32:5913549 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13550 HttpRequestInfo request0;
13551 request0.method = "GET";
13552 request0.url = GURL(url0);
13553 request0.load_flags = 0;
13554 TestCompletionCallback callback0;
13555
13556 int rv = trans0->Start(&request0, callback0.callback(), BoundNetLog());
13557 EXPECT_EQ(ERR_IO_PENDING, rv);
13558 rv = callback0.WaitForResult();
13559 EXPECT_EQ(OK, rv);
13560 }
13561
13562 // Second request to origin.
danakj1fd259a02016-04-16 03:17:0913563 std::unique_ptr<HttpTransaction> trans1(
bnc1b0e36852015-04-28 15:32:5913564 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13565 HttpRequestInfo request1;
13566 request1.method = "GET";
13567 request1.url = GURL(url1);
13568 request1.load_flags = 0;
13569 TestCompletionCallback callback1;
13570
13571 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
13572 EXPECT_EQ(ERR_IO_PENDING, rv);
fdoray92e35a72016-06-10 15:54:5513573 base::RunLoop().RunUntilIdle();
mmenkee24011922015-12-17 22:12:5913574 if (data.IsPaused())
13575 data.Resume();
bnc1b0e36852015-04-28 15:32:5913576 rv = callback1.WaitForResult();
13577 if (valid) {
13578 EXPECT_EQ(OK, rv);
13579 } else {
13580 if (pooling) {
13581 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
13582 } else {
13583 EXPECT_EQ(ERR_ALTERNATIVE_CERT_NOT_VALID_FOR_ORIGIN, rv);
13584 }
13585 }
13586 }
13587};
13588
rdsmithebb50aa2015-11-12 03:44:3813589INSTANTIATE_TEST_CASE_P(ProtoPlusDepend,
bnc1b0e36852015-04-28 15:32:5913590 AltSvcCertificateVerificationTest,
rdsmithebb50aa2015-11-12 03:44:3813591 testing::Values(kTestCaseSPDY31,
13592 kTestCaseHTTP2NoPriorityDependencies,
13593 kTestCaseHTTP2PriorityDependencies));
bnc1b0e36852015-04-28 15:32:5913594
13595// The alternative service host must exhibit a certificate that is valid for the
13596// origin host. Test that this is enforced when pooling to an existing
13597// connection.
13598TEST_P(AltSvcCertificateVerificationTest, PoolingValid) {
13599 Run(true, true);
13600}
13601
13602TEST_P(AltSvcCertificateVerificationTest, PoolingInvalid) {
13603 Run(true, false);
13604}
13605
13606// The alternative service host must exhibit a certificate that is valid for the
13607// origin host. Test that this is enforced when opening a new connection.
13608TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
13609 Run(false, true);
13610}
13611
bnc8bef8da22016-05-30 01:28:2513612// TODO(bnc): Re-enable when https://crbug.com/615413 is fixed.
13613TEST_P(AltSvcCertificateVerificationTest, DISABLED_NewConnectionInvalid) {
bnc1b0e36852015-04-28 15:32:5913614 Run(false, false);
13615}
13616
bnc5452e2a2015-05-08 16:27:4213617// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
13618// with the alternative server. That connection should not be used.
13619TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2513620 url::SchemeHostPort server("https", "www.example.org", 443);
13621 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4213622
bnc8bef8da22016-05-30 01:28:2513623 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4213624 SSLSocketDataProvider ssl(ASYNC, OK);
13625 ssl.SetNextProto(kProtoHTTP11);
13626 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13627
13628 // No data should be read from the alternative, because HTTP/1.1 is
13629 // negotiated.
13630 StaticSocketDataProvider data;
13631 session_deps_.socket_factory->AddSocketDataProvider(&data);
13632
13633 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4613634 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4213635 // mocked. This way the request relies on the alternate Job.
13636 StaticSocketDataProvider data_refused;
13637 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13638 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13639
zhongyi3d4a55e72016-04-22 20:36:4613640 // Set up alternative service for server.
bncf33fb31b2016-01-29 15:22:2613641 session_deps_.enable_alternative_service_with_different_host = true;
danakj1fd259a02016-04-16 03:17:0913642 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4013643 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4213644 session->http_server_properties();
13645 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813646 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213647 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613648 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013649 expiration);
bnc5452e2a2015-05-08 16:27:4213650
danakj1fd259a02016-04-16 03:17:0913651 std::unique_ptr<HttpTransaction> trans(
bnc5452e2a2015-05-08 16:27:4213652 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13653 HttpRequestInfo request;
13654 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2513655 request.url = GURL("https://www.example.org:443");
bnc5452e2a2015-05-08 16:27:4213656 request.load_flags = 0;
13657 TestCompletionCallback callback;
13658
13659 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
13660 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
13661 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
13662 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
13663}
13664
bnc40448a532015-05-11 19:13:1413665// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4613666// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1413667// succeeds, the request should succeed, even if the latter fails because
13668// HTTP/1.1 is negotiated which is insufficient for alternative service.
13669TEST_P(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2513670 url::SchemeHostPort server("https", "www.example.org", 443);
13671 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1413672
13673 // Negotiate HTTP/1.1 with alternative.
13674 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
13675 alternative_ssl.SetNextProto(kProtoHTTP11);
13676 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
13677
13678 // No data should be read from the alternative, because HTTP/1.1 is
13679 // negotiated.
13680 StaticSocketDataProvider data;
13681 session_deps_.socket_factory->AddSocketDataProvider(&data);
13682
zhongyi3d4a55e72016-04-22 20:36:4613683 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1413684 SSLSocketDataProvider origin_ssl(ASYNC, OK);
13685 origin_ssl.SetNextProto(kProtoHTTP11);
13686 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
13687
13688 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2513689 MockWrite("GET / HTTP/1.1\r\n"
13690 "Host: www.example.org\r\n"
13691 "Connection: keep-alive\r\n\r\n"),
13692 MockWrite("GET /second HTTP/1.1\r\n"
13693 "Host: www.example.org\r\n"
13694 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1413695 };
13696
13697 MockRead http_reads[] = {
13698 MockRead("HTTP/1.1 200 OK\r\n"),
13699 MockRead("Content-Type: text/html\r\n"),
13700 MockRead("Content-Length: 6\r\n\r\n"),
13701 MockRead("foobar"),
13702 MockRead("HTTP/1.1 200 OK\r\n"),
13703 MockRead("Content-Type: text/html\r\n"),
13704 MockRead("Content-Length: 7\r\n\r\n"),
13705 MockRead("another"),
13706 };
13707 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13708 http_writes, arraysize(http_writes));
13709 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13710
zhongyi3d4a55e72016-04-22 20:36:4613711 // Set up alternative service for server.
bncf33fb31b2016-01-29 15:22:2613712 session_deps_.enable_alternative_service_with_different_host = true;
danakj1fd259a02016-04-16 03:17:0913713 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4013714 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1413715 session->http_server_properties();
13716 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813717 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213718 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613719 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013720 expiration);
bnc40448a532015-05-11 19:13:1413721
13722 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13723 HttpRequestInfo request1;
13724 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2513725 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1413726 request1.load_flags = 0;
13727 TestCompletionCallback callback1;
13728
13729 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
13730 rv = callback1.GetResult(rv);
13731 EXPECT_EQ(OK, rv);
13732
13733 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5213734 ASSERT_TRUE(response1);
13735 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1413736 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13737
13738 std::string response_data1;
13739 ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data1));
13740 EXPECT_EQ("foobar", response_data1);
13741
13742 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
13743 // for alternative service.
13744 EXPECT_TRUE(
13745 http_server_properties->IsAlternativeServiceBroken(alternative_service));
13746
zhongyi3d4a55e72016-04-22 20:36:4613747 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1413748 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4613749 // to server.
bnc40448a532015-05-11 19:13:1413750 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13751 HttpRequestInfo request2;
13752 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2513753 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1413754 request2.load_flags = 0;
13755 TestCompletionCallback callback2;
13756
13757 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
13758 rv = callback2.GetResult(rv);
13759 EXPECT_EQ(OK, rv);
13760
13761 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5213762 ASSERT_TRUE(response2);
13763 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1413764 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
13765
13766 std::string response_data2;
13767 ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data2));
13768 EXPECT_EQ("another", response_data2);
13769}
13770
bnc5452e2a2015-05-08 16:27:4213771// Alternative service requires HTTP/2 (or SPDY), but there is already a
13772// HTTP/1.1 socket open to the alternative server. That socket should not be
13773// used.
13774TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4613775 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4213776 HostPortPair alternative("alternative.example.org", 443);
13777 std::string origin_url = "https://origin.example.org:443";
13778 std::string alternative_url = "https://alternative.example.org:443";
13779
13780 // Negotiate HTTP/1.1 with alternative.example.org.
13781 SSLSocketDataProvider ssl(ASYNC, OK);
13782 ssl.SetNextProto(kProtoHTTP11);
13783 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
13784
13785 // HTTP/1.1 data for |request1| and |request2|.
13786 MockWrite http_writes[] = {
13787 MockWrite(
13788 "GET / HTTP/1.1\r\n"
13789 "Host: alternative.example.org\r\n"
13790 "Connection: keep-alive\r\n\r\n"),
13791 MockWrite(
13792 "GET / HTTP/1.1\r\n"
13793 "Host: alternative.example.org\r\n"
13794 "Connection: keep-alive\r\n\r\n"),
13795 };
13796
13797 MockRead http_reads[] = {
13798 MockRead(
13799 "HTTP/1.1 200 OK\r\n"
13800 "Content-Type: text/html; charset=iso-8859-1\r\n"
13801 "Content-Length: 40\r\n\r\n"
13802 "first HTTP/1.1 response from alternative"),
13803 MockRead(
13804 "HTTP/1.1 200 OK\r\n"
13805 "Content-Type: text/html; charset=iso-8859-1\r\n"
13806 "Content-Length: 41\r\n\r\n"
13807 "second HTTP/1.1 response from alternative"),
13808 };
13809 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
13810 http_writes, arraysize(http_writes));
13811 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
13812
13813 // This test documents that an alternate Job should not pool to an already
13814 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4613815 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4213816 StaticSocketDataProvider data_refused;
13817 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
13818 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
13819
zhongyi3d4a55e72016-04-22 20:36:4613820 // Set up alternative service for server.
bncf33fb31b2016-01-29 15:22:2613821 session_deps_.enable_alternative_service_with_different_host = false;
danakj1fd259a02016-04-16 03:17:0913822 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4013823 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4213824 session->http_server_properties();
13825 AlternativeService alternative_service(
rdsmithebb50aa2015-11-12 03:44:3813826 AlternateProtocolFromNextProto(GetProtocol()), alternative);
bnc7dc7e1b42015-07-28 14:43:1213827 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyi3d4a55e72016-04-22 20:36:4613828 http_server_properties->SetAlternativeService(server, alternative_service,
rchdc7b9052016-03-17 20:51:5013829 expiration);
bnc5452e2a2015-05-08 16:27:4213830
13831 // First transaction to alternative to open an HTTP/1.1 socket.
danakj1fd259a02016-04-16 03:17:0913832 std::unique_ptr<HttpTransaction> trans1(
bnc5452e2a2015-05-08 16:27:4213833 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13834 HttpRequestInfo request1;
13835 request1.method = "GET";
13836 request1.url = GURL(alternative_url);
13837 request1.load_flags = 0;
13838 TestCompletionCallback callback1;
13839
13840 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
13841 EXPECT_EQ(OK, callback1.GetResult(rv));
13842 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
13843 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5213844 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4213845 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
13846 EXPECT_TRUE(response1->was_npn_negotiated);
13847 EXPECT_FALSE(response1->was_fetched_via_spdy);
13848 std::string response_data1;
13849 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
13850 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
13851
13852 // Request for origin.example.org, which has an alternative service. This
13853 // will start two Jobs: the alternative looks for connections to pool to,
13854 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4613855 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4213856 // this request fails.
danakj1fd259a02016-04-16 03:17:0913857 std::unique_ptr<HttpTransaction> trans2(
bnc5452e2a2015-05-08 16:27:4213858 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13859 HttpRequestInfo request2;
13860 request2.method = "GET";
13861 request2.url = GURL(origin_url);
13862 request2.load_flags = 0;
13863 TestCompletionCallback callback2;
13864
13865 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
13866 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
13867
13868 // Another transaction to alternative. This is to test that the HTTP/1.1
13869 // socket is still open and in the pool.
danakj1fd259a02016-04-16 03:17:0913870 std::unique_ptr<HttpTransaction> trans3(
bnc5452e2a2015-05-08 16:27:4213871 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
13872 HttpRequestInfo request3;
13873 request3.method = "GET";
13874 request3.url = GURL(alternative_url);
13875 request3.load_flags = 0;
13876 TestCompletionCallback callback3;
13877
13878 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
13879 EXPECT_EQ(OK, callback3.GetResult(rv));
13880 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
13881 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5213882 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4213883 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
13884 EXPECT_TRUE(response3->was_npn_negotiated);
13885 EXPECT_FALSE(response3->was_fetched_via_spdy);
13886 std::string response_data3;
13887 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
13888 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
13889}
13890
[email protected]23e482282013-06-14 16:08:0213891TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2313892 const std::string https_url = "https://www.example.org:8080/";
13893 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0413894
rdsmithebb50aa2015-11-12 03:44:3813895 // Separate SPDY util instance for naked and wrapped requests.
13896 SpdyTestUtil spdy_util_wrapped(GetProtocol(), GetDependenciesFromPriority());
13897
[email protected]8450d722012-07-02 19:14:0413898 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2313899 const HostPortPair host_port_pair("www.example.org", 8080);
danakj1fd259a02016-04-16 03:17:0913900 std::unique_ptr<SpdySerializedFrame> connect(
lgarrona91df87f2014-12-05 00:51:3413901 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
danakj1fd259a02016-04-16 03:17:0913902 std::unique_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4913903 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
danakj1fd259a02016-04-16 03:17:0913904 std::unique_ptr<SpdySerializedFrame> wrapped_req1(
[email protected]23e482282013-06-14 16:08:0213905 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3913906
13907 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
[email protected]745aa9c2014-06-27 02:21:2913908 SpdyHeaderBlock req2_block;
bnc7ecc1122015-09-28 13:22:4913909 spdy_util_.MaybeAddVersionHeader(&req2_block);
[email protected]745aa9c2014-06-27 02:21:2913910 req2_block[spdy_util_.GetMethodKey()] = "GET";
bncce36dca22015-04-21 22:11:2313911 req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
[email protected]745aa9c2014-06-27 02:21:2913912 req2_block[spdy_util_.GetSchemeKey()] = "http";
bnc7ecc1122015-09-28 13:22:4913913 req2_block[spdy_util_.GetPathKey()] = "/";
danakj1fd259a02016-04-16 03:17:0913914 std::unique_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4913915 spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0413916
13917 MockWrite writes1[] = {
mmenke666a6fea2015-12-19 04:16:3313918 CreateMockWrite(*connect, 0), CreateMockWrite(*wrapped_req1, 2),
13919 CreateMockWrite(*req2, 6),
[email protected]8450d722012-07-02 19:14:0413920 };
13921
danakj1fd259a02016-04-16 03:17:0913922 std::unique_ptr<SpdySerializedFrame> conn_resp(
bnc38dcd392016-02-09 23:19:4913923 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
danakj1fd259a02016-04-16 03:17:0913924 std::unique_ptr<SpdySerializedFrame> resp1(
bnc38dcd392016-02-09 23:19:4913925 spdy_util_wrapped.ConstructSpdyGetSynReply(nullptr, 0, 1));
danakj1fd259a02016-04-16 03:17:0913926 std::unique_ptr<SpdySerializedFrame> body1(
bnc38dcd392016-02-09 23:19:4913927 spdy_util_wrapped.ConstructSpdyBodyFrame(1, true));
danakj1fd259a02016-04-16 03:17:0913928 std::unique_ptr<SpdySerializedFrame> wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3813929 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
danakj1fd259a02016-04-16 03:17:0913930 std::unique_ptr<SpdySerializedFrame> wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3813931 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
danakj1fd259a02016-04-16 03:17:0913932 std::unique_ptr<SpdySerializedFrame> resp2(
bncb03b1092016-04-06 11:19:5513933 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
danakj1fd259a02016-04-16 03:17:0913934 std::unique_ptr<SpdySerializedFrame> body2(
bncb03b1092016-04-06 11:19:5513935 spdy_util_.ConstructSpdyBodyFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3313936 MockRead reads1[] = {
13937 CreateMockRead(*conn_resp, 1),
13938 MockRead(ASYNC, ERR_IO_PENDING, 3),
13939 CreateMockRead(*wrapped_resp1, 4),
13940 CreateMockRead(*wrapped_body1, 5),
13941 MockRead(ASYNC, ERR_IO_PENDING, 7),
13942 CreateMockRead(*resp2, 8),
13943 CreateMockRead(*body2, 9),
13944 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
13945 };
[email protected]8450d722012-07-02 19:14:0413946
mmenke666a6fea2015-12-19 04:16:3313947 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
13948 arraysize(writes1));
[email protected]8450d722012-07-02 19:14:0413949 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5713950 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0413951
rdsmith82957ad2015-09-16 19:42:0313952 session_deps_.proxy_service =
13953 ProxyService::CreateFixedFromPacResult("HTTPS proxy:70");
vishal.b62985ca92015-04-17 08:45:5113954 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713955 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0413956 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
rdsmithebb50aa2015-11-12 03:44:3813957 ssl1.SetNextProto(GetProtocol());
mmenke666a6fea2015-12-19 04:16:3313958 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0413959 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
rdsmithebb50aa2015-11-12 03:44:3813960 ssl2.SetNextProto(GetProtocol());
mmenke666a6fea2015-12-19 04:16:3313961 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
13962 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0413963
danakj1fd259a02016-04-16 03:17:0913964 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0413965
13966 // Start the first transaction to set up the SpdySession
13967 HttpRequestInfo request1;
13968 request1.method = "GET";
13969 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0413970 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013971 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0413972 TestCompletionCallback callback1;
mmenke666a6fea2015-12-19 04:16:3313973 int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog());
[email protected]8450d722012-07-02 19:14:0413974
mmenke666a6fea2015-12-19 04:16:3313975 // This pause is a hack to avoid running into https://crbug.com/497228.
13976 data1.RunUntilPaused();
13977 base::RunLoop().RunUntilIdle();
13978 data1.Resume();
13979 EXPECT_EQ(OK, callback1.GetResult(rv));
[email protected]8450d722012-07-02 19:14:0413980 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
13981
[email protected]f6c63db52013-02-02 00:35:2213982 LoadTimingInfo load_timing_info1;
13983 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
13984 TestLoadTimingNotReusedWithPac(load_timing_info1,
13985 CONNECT_TIMING_HAS_SSL_TIMES);
13986
mmenke666a6fea2015-12-19 04:16:3313987 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0413988 HttpRequestInfo request2;
13989 request2.method = "GET";
13990 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0413991 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5013992 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0413993 TestCompletionCallback callback2;
mmenke666a6fea2015-12-19 04:16:3313994 rv = trans2.Start(&request2, callback2.callback(), BoundNetLog());
[email protected]8450d722012-07-02 19:14:0413995
mmenke666a6fea2015-12-19 04:16:3313996 // This pause is a hack to avoid running into https://crbug.com/497228.
13997 data1.RunUntilPaused();
13998 base::RunLoop().RunUntilIdle();
13999 data1.Resume();
14000 EXPECT_EQ(OK, callback2.GetResult(rv));
14001
[email protected]8450d722012-07-02 19:14:0414002 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2214003
14004 LoadTimingInfo load_timing_info2;
14005 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
14006 // The established SPDY sessions is considered reused by the HTTP request.
14007 TestLoadTimingReusedWithPac(load_timing_info2);
14008 // HTTP requests over a SPDY session should have a different connection
14009 // socket_log_id than requests over a tunnel.
14010 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0414011}
14012
[email protected]2d88e7d2012-07-19 17:55:1714013// Test that in the case where we have a SPDY session to a SPDY proxy
14014// that we do not pool other origins that resolve to the same IP when
14015// the certificate does not match the new origin.
14016// http://crbug.com/134690
[email protected]23e482282013-06-14 16:08:0214017TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2314018 const std::string url1 = "http://www.example.org/";
14019 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1714020 const std::string ip_addr = "1.2.3.4";
14021
rdsmithebb50aa2015-11-12 03:44:3814022 // Second SpdyTestUtil instance for the second socket.
14023 SpdyTestUtil spdy_util_secure(GetProtocol(), GetDependenciesFromPriority());
14024
[email protected]2d88e7d2012-07-19 17:55:1714025 // SPDY GET for HTTP URL (through SPDY proxy)
danakj1fd259a02016-04-16 03:17:0914026 std::unique_ptr<SpdyHeaderBlock> headers(
bncce36dca22015-04-21 22:11:2314027 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
danakj1fd259a02016-04-16 03:17:0914028 std::unique_ptr<SpdySerializedFrame> req1(
bnc38dcd392016-02-09 23:19:4914029 spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1714030
14031 MockWrite writes1[] = {
14032 CreateMockWrite(*req1, 0),
14033 };
14034
danakj1fd259a02016-04-16 03:17:0914035 std::unique_ptr<SpdySerializedFrame> resp1(
bncb03b1092016-04-06 11:19:5514036 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0914037 std::unique_ptr<SpdySerializedFrame> body1(
bncb03b1092016-04-06 11:19:5514038 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1714039 MockRead reads1[] = {
mmenke666a6fea2015-12-19 04:16:3314040 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(*resp1, 2),
14041 CreateMockRead(*body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1714042 };
14043
mmenke666a6fea2015-12-19 04:16:3314044 SequencedSocketData data1(reads1, arraysize(reads1), writes1,
14045 arraysize(writes1));
martijnfe9636e2016-02-06 14:33:3214046 IPAddress ip;
martijn654c8c42016-02-10 22:10:5914047 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1714048 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14049 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3314050 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1714051
14052 // SPDY GET for HTTPS URL (direct)
danakj1fd259a02016-04-16 03:17:0914053 std::unique_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4914054 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1714055
14056 MockWrite writes2[] = {
14057 CreateMockWrite(*req2, 0),
14058 };
14059
danakj1fd259a02016-04-16 03:17:0914060 std::unique_ptr<SpdySerializedFrame> resp2(
rdsmithebb50aa2015-11-12 03:44:3814061 spdy_util_secure.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0914062 std::unique_ptr<SpdySerializedFrame> body2(
bncb03b1092016-04-06 11:19:5514063 spdy_util_secure.ConstructSpdyBodyFrame(1, true));
mmenke666a6fea2015-12-19 04:16:3314064 MockRead reads2[] = {CreateMockRead(*resp2, 1), CreateMockRead(*body2, 2),
14065 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1714066
mmenke666a6fea2015-12-19 04:16:3314067 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14068 arraysize(writes2));
[email protected]2d88e7d2012-07-19 17:55:1714069 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3314070 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1714071
14072 // Set up a proxy config that sends HTTP requests to a proxy, and
14073 // all others direct.
14074 ProxyConfig proxy_config;
14075 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
[email protected]bb88e1d32013-05-03 23:11:0714076 session_deps_.proxy_service.reset(new ProxyService(
danakj1fd259a02016-04-16 03:17:0914077 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)), nullptr,
csharrisonb7e3a082015-09-22 19:13:0414078 NULL));
[email protected]2d88e7d2012-07-19 17:55:1714079
bncce36dca22015-04-21 22:11:2314080 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
rdsmithebb50aa2015-11-12 03:44:3814081 ssl1.SetNextProto(GetProtocol());
[email protected]2d88e7d2012-07-19 17:55:1714082 // Load a valid cert. Note, that this does not need to
14083 // be valid for proxy because the MockSSLClientSocket does
14084 // not actually verify it. But SpdySession will use this
14085 // to see if it is valid for the new origin
bncce36dca22015-04-21 22:11:2314086 ssl1.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
wezca1070932016-05-26 20:30:5214087 ASSERT_TRUE(ssl1.cert);
mmenke666a6fea2015-12-19 04:16:3314088 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14089 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1714090
14091 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
rdsmithebb50aa2015-11-12 03:44:3814092 ssl2.SetNextProto(GetProtocol());
mmenke666a6fea2015-12-19 04:16:3314093 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14094 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1714095
[email protected]bb88e1d32013-05-03 23:11:0714096 session_deps_.host_resolver.reset(new MockCachingHostResolver());
bncce36dca22015-04-21 22:11:2314097 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0714098 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1714099
danakj1fd259a02016-04-16 03:17:0914100 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1714101
14102 // Start the first transaction to set up the SpdySession
14103 HttpRequestInfo request1;
14104 request1.method = "GET";
14105 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1714106 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014107 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714108 TestCompletionCallback callback1;
14109 ASSERT_EQ(ERR_IO_PENDING,
14110 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
mmenke666a6fea2015-12-19 04:16:3314111 // This pause is a hack to avoid running into https://crbug.com/497228.
14112 data1.RunUntilPaused();
14113 base::RunLoop().RunUntilIdle();
14114 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1714115
[email protected]2d88e7d2012-07-19 17:55:1714116 EXPECT_EQ(OK, callback1.WaitForResult());
14117 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
14118
14119 // Now, start the HTTP request
14120 HttpRequestInfo request2;
14121 request2.method = "GET";
14122 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1714123 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014124 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1714125 TestCompletionCallback callback2;
14126 EXPECT_EQ(ERR_IO_PENDING,
14127 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
fdoray92e35a72016-06-10 15:54:5514128 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1714129
14130 ASSERT_TRUE(callback2.have_result());
14131 EXPECT_EQ(OK, callback2.WaitForResult());
14132 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14133}
14134
[email protected]85f97342013-04-17 06:12:2414135// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
14136// error) in SPDY session, removes the socket from pool and closes the SPDY
14137// session. Verify that new url's from the same HttpNetworkSession (and a new
14138// SpdySession) do work. http://crbug.com/224701
[email protected]23e482282013-06-14 16:08:0214139TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2314140 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2414141
14142 MockRead reads1[] = {
14143 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
14144 };
14145
mmenke11eb5152015-06-09 14:50:5014146 SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
[email protected]85f97342013-04-17 06:12:2414147
danakj1fd259a02016-04-16 03:17:0914148 std::unique_ptr<SpdySerializedFrame> req2(
bnc38dcd392016-02-09 23:19:4914149 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2414150 MockWrite writes2[] = {
14151 CreateMockWrite(*req2, 0),
14152 };
14153
danakj1fd259a02016-04-16 03:17:0914154 std::unique_ptr<SpdySerializedFrame> resp2(
bncb03b1092016-04-06 11:19:5514155 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0914156 std::unique_ptr<SpdySerializedFrame> body2(
bncb03b1092016-04-06 11:19:5514157 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]85f97342013-04-17 06:12:2414158 MockRead reads2[] = {
14159 CreateMockRead(*resp2, 1),
14160 CreateMockRead(*body2, 2),
14161 MockRead(ASYNC, OK, 3) // EOF
14162 };
14163
mmenke11eb5152015-06-09 14:50:5014164 SequencedSocketData data2(reads2, arraysize(reads2), writes2,
14165 arraysize(writes2));
[email protected]85f97342013-04-17 06:12:2414166
[email protected]85f97342013-04-17 06:12:2414167 SSLSocketDataProvider ssl1(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3814168 ssl1.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:5014169 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14170 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2414171
14172 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3814173 ssl2.SetNextProto(GetProtocol());
mmenke11eb5152015-06-09 14:50:5014174 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14175 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2414176
danakj1fd259a02016-04-16 03:17:0914177 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5014178 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2414179
14180 // Start the first transaction to set up the SpdySession and verify that
14181 // connection was closed.
14182 HttpRequestInfo request1;
14183 request1.method = "GET";
14184 request1.url = GURL(https_url);
14185 request1.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014186 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414187 TestCompletionCallback callback1;
14188 EXPECT_EQ(ERR_IO_PENDING,
14189 trans1.Start(&request1, callback1.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2414190 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
14191
14192 // Now, start the second request and make sure it succeeds.
14193 HttpRequestInfo request2;
14194 request2.method = "GET";
14195 request2.url = GURL(https_url);
14196 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014197 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2414198 TestCompletionCallback callback2;
14199 EXPECT_EQ(ERR_IO_PENDING,
14200 trans2.Start(&request2, callback2.callback(), BoundNetLog()));
[email protected]85f97342013-04-17 06:12:2414201
mmenke11eb5152015-06-09 14:50:5014202 ASSERT_EQ(OK, callback2.WaitForResult());
[email protected]85f97342013-04-17 06:12:2414203 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
14204}
14205
[email protected]23e482282013-06-14 16:08:0214206TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0314207 ClientSocketPoolManager::set_max_sockets_per_group(
14208 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14209 ClientSocketPoolManager::set_max_sockets_per_pool(
14210 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
14211
14212 // Use two different hosts with different IPs so they don't get pooled.
14213 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
14214 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0914215 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0314216
14217 SSLSocketDataProvider ssl1(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3814218 ssl1.SetNextProto(GetProtocol());
[email protected]483fa202013-05-14 01:07:0314219 SSLSocketDataProvider ssl2(ASYNC, OK);
rdsmithebb50aa2015-11-12 03:44:3814220 ssl2.SetNextProto(GetProtocol());
[email protected]483fa202013-05-14 01:07:0314221 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
14222 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
14223
danakj1fd259a02016-04-16 03:17:0914224 std::unique_ptr<SpdySerializedFrame> host1_req(
bnc38dcd392016-02-09 23:19:4914225 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314226 MockWrite spdy1_writes[] = {
rch8e6c6c42015-05-01 14:05:1314227 CreateMockWrite(*host1_req, 0),
[email protected]483fa202013-05-14 01:07:0314228 };
danakj1fd259a02016-04-16 03:17:0914229 std::unique_ptr<SpdySerializedFrame> host1_resp(
[email protected]23e482282013-06-14 16:08:0214230 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0914231 std::unique_ptr<SpdySerializedFrame> host1_resp_body(
[email protected]23e482282013-06-14 16:08:0214232 spdy_util_.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314233 MockRead spdy1_reads[] = {
mmenkee24011922015-12-17 22:12:5914234 CreateMockRead(*host1_resp, 1), CreateMockRead(*host1_resp_body, 2),
14235 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314236 };
14237
rdsmithebb50aa2015-11-12 03:44:3814238 // Use a separate test instance for the separate SpdySession that will be
14239 // created.
14240 SpdyTestUtil spdy_util_2(GetProtocol(), GetDependenciesFromPriority());
danakj1fd259a02016-04-16 03:17:0914241 std::unique_ptr<SequencedSocketData> spdy1_data(
rch8e6c6c42015-05-01 14:05:1314242 new SequencedSocketData(spdy1_reads, arraysize(spdy1_reads), spdy1_writes,
14243 arraysize(spdy1_writes)));
[email protected]483fa202013-05-14 01:07:0314244 session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
14245
danakj1fd259a02016-04-16 03:17:0914246 std::unique_ptr<SpdySerializedFrame> host2_req(
bnc38dcd392016-02-09 23:19:4914247 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0314248 MockWrite spdy2_writes[] = {
rch8e6c6c42015-05-01 14:05:1314249 CreateMockWrite(*host2_req, 0),
[email protected]483fa202013-05-14 01:07:0314250 };
danakj1fd259a02016-04-16 03:17:0914251 std::unique_ptr<SpdySerializedFrame> host2_resp(
rdsmithebb50aa2015-11-12 03:44:3814252 spdy_util_2.ConstructSpdyGetSynReply(NULL, 0, 1));
danakj1fd259a02016-04-16 03:17:0914253 std::unique_ptr<SpdySerializedFrame> host2_resp_body(
rdsmithebb50aa2015-11-12 03:44:3814254 spdy_util_2.ConstructSpdyBodyFrame(1, true));
[email protected]483fa202013-05-14 01:07:0314255 MockRead spdy2_reads[] = {
mmenkee24011922015-12-17 22:12:5914256 CreateMockRead(*host2_resp, 1), CreateMockRead(*host2_resp_body, 2),
14257 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0314258 };
14259
danakj1fd259a02016-04-16 03:17:0914260 std::unique_ptr<SequencedSocketData> spdy2_data(
rch8e6c6c42015-05-01 14:05:1314261 new SequencedSocketData(spdy2_reads, arraysize(spdy2_reads), spdy2_writes,
14262 arraysize(spdy2_writes)));
[email protected]483fa202013-05-14 01:07:0314263 session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
14264
14265 MockWrite http_write[] = {
14266 MockWrite("GET / HTTP/1.1\r\n"
14267 "Host: www.a.com\r\n"
14268 "Connection: keep-alive\r\n\r\n"),
14269 };
14270
14271 MockRead http_read[] = {
14272 MockRead("HTTP/1.1 200 OK\r\n"),
14273 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14274 MockRead("Content-Length: 6\r\n\r\n"),
14275 MockRead("hello!"),
14276 };
14277 StaticSocketDataProvider http_data(http_read, arraysize(http_read),
14278 http_write, arraysize(http_write));
14279 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
14280
14281 HostPortPair host_port_pair_a("www.a.com", 443);
[email protected]e6d017652013-05-17 18:01:4014282 SpdySessionKey spdy_session_key_a(
[email protected]314b03992014-04-01 01:28:5314283 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314284 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614285 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314286
14287 TestCompletionCallback callback;
14288 HttpRequestInfo request1;
14289 request1.method = "GET";
14290 request1.url = GURL("https://www.a.com/");
14291 request1.load_flags = 0;
danakj1fd259a02016-04-16 03:17:0914292 std::unique_ptr<HttpNetworkTransaction> trans(
[email protected]90499482013-06-01 00:39:5014293 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314294
14295 int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
14296 EXPECT_EQ(ERR_IO_PENDING, rv);
14297 EXPECT_EQ(OK, callback.WaitForResult());
14298
14299 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214300 ASSERT_TRUE(response);
14301 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214302 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314303 EXPECT_TRUE(response->was_fetched_via_spdy);
14304 EXPECT_TRUE(response->was_npn_negotiated);
14305
14306 std::string response_data;
14307 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14308 EXPECT_EQ("hello!", response_data);
14309 trans.reset();
14310 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614311 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314312
14313 HostPortPair host_port_pair_b("www.b.com", 443);
[email protected]e6d017652013-05-17 18:01:4014314 SpdySessionKey spdy_session_key_b(
[email protected]314b03992014-04-01 01:28:5314315 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314316 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614317 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314318 HttpRequestInfo request2;
14319 request2.method = "GET";
14320 request2.url = GURL("https://www.b.com/");
14321 request2.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014322 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314323
14324 rv = trans->Start(&request2, callback.callback(), BoundNetLog());
14325 EXPECT_EQ(ERR_IO_PENDING, rv);
14326 EXPECT_EQ(OK, callback.WaitForResult());
14327
14328 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214329 ASSERT_TRUE(response);
14330 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214331 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0314332 EXPECT_TRUE(response->was_fetched_via_spdy);
14333 EXPECT_TRUE(response->was_npn_negotiated);
14334 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14335 EXPECT_EQ("hello!", response_data);
14336 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614337 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314338 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2614339 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314340
14341 HostPortPair host_port_pair_a1("www.a.com", 80);
[email protected]e6d017652013-05-17 18:01:4014342 SpdySessionKey spdy_session_key_a1(
[email protected]314b03992014-04-01 01:28:5314343 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
[email protected]483fa202013-05-14 01:07:0314344 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614345 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0314346 HttpRequestInfo request3;
14347 request3.method = "GET";
14348 request3.url = GURL("http://www.a.com/");
14349 request3.load_flags = 0;
[email protected]90499482013-06-01 00:39:5014350 trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]483fa202013-05-14 01:07:0314351
14352 rv = trans->Start(&request3, callback.callback(), BoundNetLog());
14353 EXPECT_EQ(ERR_IO_PENDING, rv);
14354 EXPECT_EQ(OK, callback.WaitForResult());
14355
14356 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5214357 ASSERT_TRUE(response);
14358 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0314359 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14360 EXPECT_FALSE(response->was_fetched_via_spdy);
14361 EXPECT_FALSE(response->was_npn_negotiated);
14362 ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
14363 EXPECT_EQ("hello!", response_data);
14364 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614365 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0314366 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2614367 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0314368}
14369
[email protected]79e1fd62013-06-20 06:50:0414370TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
14371 HttpRequestInfo request;
14372 request.method = "GET";
bncce36dca22015-04-21 22:11:2314373 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414374 request.load_flags = 0;
14375
danakj1fd259a02016-04-16 03:17:0914376 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14377 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114378 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414379
ttuttled9dbc652015-09-29 20:00:5914380 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414381 StaticSocketDataProvider data;
14382 data.set_connect_data(mock_connect);
14383 session_deps_.socket_factory->AddSocketDataProvider(&data);
14384
14385 TestCompletionCallback callback;
14386
14387 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14388 EXPECT_EQ(ERR_IO_PENDING, rv);
14389
14390 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5914391 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0414392
[email protected]79e1fd62013-06-20 06:50:0414393 // We don't care whether this succeeds or fails, but it shouldn't crash.
14394 HttpRequestHeaders request_headers;
14395 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714396
14397 ConnectionAttempts attempts;
14398 trans->GetConnectionAttempts(&attempts);
14399 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5914400 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
14401
14402 IPEndPoint endpoint;
14403 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
14404 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414405}
14406
14407TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
14408 HttpRequestInfo request;
14409 request.method = "GET";
bncce36dca22015-04-21 22:11:2314410 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414411 request.load_flags = 0;
14412
danakj1fd259a02016-04-16 03:17:0914413 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14414 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114415 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414416
ttuttled9dbc652015-09-29 20:00:5914417 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0414418 StaticSocketDataProvider data;
14419 data.set_connect_data(mock_connect);
14420 session_deps_.socket_factory->AddSocketDataProvider(&data);
14421
14422 TestCompletionCallback callback;
14423
14424 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14425 EXPECT_EQ(ERR_IO_PENDING, rv);
14426
14427 rv = callback.WaitForResult();
ttuttled9dbc652015-09-29 20:00:5914428 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
[email protected]79e1fd62013-06-20 06:50:0414429
[email protected]79e1fd62013-06-20 06:50:0414430 // We don't care whether this succeeds or fails, but it shouldn't crash.
14431 HttpRequestHeaders request_headers;
14432 trans->GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4714433
14434 ConnectionAttempts attempts;
14435 trans->GetConnectionAttempts(&attempts);
14436 ASSERT_EQ(1u, attempts.size());
ttuttled9dbc652015-09-29 20:00:5914437 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, attempts[0].result);
14438
14439 IPEndPoint endpoint;
14440 EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint));
14441 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0414442}
14443
14444TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
14445 HttpRequestInfo request;
14446 request.method = "GET";
bncce36dca22015-04-21 22:11:2314447 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414448 request.load_flags = 0;
14449
danakj1fd259a02016-04-16 03:17:0914450 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14451 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114452 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414453
14454 MockWrite data_writes[] = {
14455 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
14456 };
14457 MockRead data_reads[] = {
14458 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14459 };
14460
14461 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14462 data_writes, arraysize(data_writes));
14463 session_deps_.socket_factory->AddSocketDataProvider(&data);
14464
14465 TestCompletionCallback callback;
14466
14467 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14468 EXPECT_EQ(ERR_IO_PENDING, rv);
14469
14470 rv = callback.WaitForResult();
14471 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14472
[email protected]79e1fd62013-06-20 06:50:0414473 HttpRequestHeaders request_headers;
14474 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14475 EXPECT_TRUE(request_headers.HasHeader("Host"));
14476}
14477
14478TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
14479 HttpRequestInfo request;
14480 request.method = "GET";
bncce36dca22015-04-21 22:11:2314481 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414482 request.load_flags = 0;
14483
danakj1fd259a02016-04-16 03:17:0914484 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14485 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114486 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414487
14488 MockWrite data_writes[] = {
14489 MockWrite(ASYNC, ERR_CONNECTION_RESET),
14490 };
14491 MockRead data_reads[] = {
14492 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
14493 };
14494
14495 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14496 data_writes, arraysize(data_writes));
14497 session_deps_.socket_factory->AddSocketDataProvider(&data);
14498
14499 TestCompletionCallback callback;
14500
14501 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14502 EXPECT_EQ(ERR_IO_PENDING, rv);
14503
14504 rv = callback.WaitForResult();
14505 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14506
[email protected]79e1fd62013-06-20 06:50:0414507 HttpRequestHeaders request_headers;
14508 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14509 EXPECT_TRUE(request_headers.HasHeader("Host"));
14510}
14511
14512TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
14513 HttpRequestInfo request;
14514 request.method = "GET";
bncce36dca22015-04-21 22:11:2314515 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414516 request.load_flags = 0;
14517
danakj1fd259a02016-04-16 03:17:0914518 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14519 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114520 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414521
14522 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314523 MockWrite(
14524 "GET / HTTP/1.1\r\n"
14525 "Host: www.example.org\r\n"
14526 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414527 };
14528 MockRead data_reads[] = {
14529 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
14530 };
14531
14532 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14533 data_writes, arraysize(data_writes));
14534 session_deps_.socket_factory->AddSocketDataProvider(&data);
14535
14536 TestCompletionCallback callback;
14537
14538 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14539 EXPECT_EQ(ERR_IO_PENDING, rv);
14540
14541 rv = callback.WaitForResult();
14542 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14543
[email protected]79e1fd62013-06-20 06:50:0414544 HttpRequestHeaders request_headers;
14545 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14546 EXPECT_TRUE(request_headers.HasHeader("Host"));
14547}
14548
14549TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
14550 HttpRequestInfo request;
14551 request.method = "GET";
bncce36dca22015-04-21 22:11:2314552 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414553 request.load_flags = 0;
14554
danakj1fd259a02016-04-16 03:17:0914555 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14556 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114557 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414558
14559 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314560 MockWrite(
14561 "GET / HTTP/1.1\r\n"
14562 "Host: www.example.org\r\n"
14563 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414564 };
14565 MockRead data_reads[] = {
14566 MockRead(ASYNC, ERR_CONNECTION_RESET),
14567 };
14568
14569 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14570 data_writes, arraysize(data_writes));
14571 session_deps_.socket_factory->AddSocketDataProvider(&data);
14572
14573 TestCompletionCallback callback;
14574
14575 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14576 EXPECT_EQ(ERR_IO_PENDING, rv);
14577
14578 rv = callback.WaitForResult();
14579 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
14580
[email protected]79e1fd62013-06-20 06:50:0414581 HttpRequestHeaders request_headers;
14582 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14583 EXPECT_TRUE(request_headers.HasHeader("Host"));
14584}
14585
14586TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
14587 HttpRequestInfo request;
14588 request.method = "GET";
bncce36dca22015-04-21 22:11:2314589 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0414590 request.load_flags = 0;
14591 request.extra_headers.SetHeader("X-Foo", "bar");
14592
danakj1fd259a02016-04-16 03:17:0914593 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14594 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4114595 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]79e1fd62013-06-20 06:50:0414596
14597 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314598 MockWrite(
14599 "GET / HTTP/1.1\r\n"
14600 "Host: www.example.org\r\n"
14601 "Connection: keep-alive\r\n"
14602 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0414603 };
14604 MockRead data_reads[] = {
14605 MockRead("HTTP/1.1 200 OK\r\n"
14606 "Content-Length: 5\r\n\r\n"
14607 "hello"),
14608 MockRead(ASYNC, ERR_UNEXPECTED),
14609 };
14610
14611 StaticSocketDataProvider data(data_reads, arraysize(data_reads),
14612 data_writes, arraysize(data_writes));
14613 session_deps_.socket_factory->AddSocketDataProvider(&data);
14614
14615 TestCompletionCallback callback;
14616
14617 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
14618 EXPECT_EQ(ERR_IO_PENDING, rv);
14619
14620 rv = callback.WaitForResult();
14621 EXPECT_EQ(OK, rv);
14622
14623 HttpRequestHeaders request_headers;
14624 EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
14625 std::string foo;
14626 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
14627 EXPECT_EQ("bar", foo);
14628}
14629
[email protected]bf828982013-08-14 18:01:4714630namespace {
14631
yhiranoa7e05bb2014-11-06 05:40:3914632// Fake HttpStream that simply records calls to SetPriority().
14633class FakeStream : public HttpStream,
[email protected]e86839fd2013-08-14 18:29:0314634 public base::SupportsWeakPtr<FakeStream> {
14635 public:
14636 explicit FakeStream(RequestPriority priority) : priority_(priority) {}
dchengb03027d2014-10-21 12:00:2014637 ~FakeStream() override {}
[email protected]e86839fd2013-08-14 18:29:0314638
14639 RequestPriority priority() const { return priority_; }
14640
dchengb03027d2014-10-21 12:00:2014641 int InitializeStream(const HttpRequestInfo* request_info,
14642 RequestPriority priority,
14643 const BoundNetLog& net_log,
14644 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314645 return ERR_IO_PENDING;
14646 }
14647
dchengb03027d2014-10-21 12:00:2014648 int SendRequest(const HttpRequestHeaders& request_headers,
14649 HttpResponseInfo* response,
14650 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314651 ADD_FAILURE();
14652 return ERR_UNEXPECTED;
14653 }
14654
dchengb03027d2014-10-21 12:00:2014655 int ReadResponseHeaders(const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314656 ADD_FAILURE();
14657 return ERR_UNEXPECTED;
14658 }
14659
dchengb03027d2014-10-21 12:00:2014660 int ReadResponseBody(IOBuffer* buf,
14661 int buf_len,
14662 const CompletionCallback& callback) override {
[email protected]e86839fd2013-08-14 18:29:0314663 ADD_FAILURE();
14664 return ERR_UNEXPECTED;
14665 }
14666
dchengb03027d2014-10-21 12:00:2014667 void Close(bool not_reusable) override {}
[email protected]e86839fd2013-08-14 18:29:0314668
dchengb03027d2014-10-21 12:00:2014669 bool IsResponseBodyComplete() const override {
[email protected]e86839fd2013-08-14 18:29:0314670 ADD_FAILURE();
14671 return false;
14672 }
14673
dchengb03027d2014-10-21 12:00:2014674 bool IsConnectionReused() const override {
[email protected]e86839fd2013-08-14 18:29:0314675 ADD_FAILURE();
14676 return false;
14677 }
14678
dchengb03027d2014-10-21 12:00:2014679 void SetConnectionReused() override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314680
mmenkebd84c392015-09-02 14:12:3414681 bool CanReuseConnection() const override { return false; }
[email protected]e86839fd2013-08-14 18:29:0314682
sclittle4de1bab92015-09-22 21:28:2414683 int64_t GetTotalReceivedBytes() const override {
[email protected]bc92bc972013-12-13 08:32:5914684 ADD_FAILURE();
14685 return 0;
14686 }
14687
sclittlebe1ccf62015-09-02 19:40:3614688 int64_t GetTotalSentBytes() const override {
14689 ADD_FAILURE();
14690 return 0;
14691 }
14692
dchengb03027d2014-10-21 12:00:2014693 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
[email protected]e86839fd2013-08-14 18:29:0314694 ADD_FAILURE();
14695 return false;
14696 }
14697
dchengb03027d2014-10-21 12:00:2014698 void GetSSLInfo(SSLInfo* ssl_info) override { ADD_FAILURE(); }
14699
14700 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
[email protected]e86839fd2013-08-14 18:29:0314701 ADD_FAILURE();
14702 }
14703
ttuttled9dbc652015-09-29 20:00:5914704 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14705
nharperb7441ef2016-01-25 23:54:1414706 Error GetSignedEKMForTokenBinding(crypto::ECPrivateKey* key,
14707 std::vector<uint8_t>* out) override {
14708 ADD_FAILURE();
14709 return ERR_NOT_IMPLEMENTED;
14710 }
14711
dchengb03027d2014-10-21 12:00:2014712 void Drain(HttpNetworkSession* session) override { ADD_FAILURE(); }
[email protected]e86839fd2013-08-14 18:29:0314713
zhongyica364fbb2015-12-12 03:39:1214714 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
14715
dchengb03027d2014-10-21 12:00:2014716 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]e86839fd2013-08-14 18:29:0314717
yhiranoa7e05bb2014-11-06 05:40:3914718 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
14719
14720 HttpStream* RenewStreamForAuth() override { return NULL; }
14721
[email protected]e86839fd2013-08-14 18:29:0314722 private:
14723 RequestPriority priority_;
14724
14725 DISALLOW_COPY_AND_ASSIGN(FakeStream);
14726};
14727
14728// Fake HttpStreamRequest that simply records calls to SetPriority()
14729// and vends FakeStreams with its current priority.
[email protected]bf828982013-08-14 18:01:4714730class FakeStreamRequest : public HttpStreamRequest,
14731 public base::SupportsWeakPtr<FakeStreamRequest> {
14732 public:
[email protected]e86839fd2013-08-14 18:29:0314733 FakeStreamRequest(RequestPriority priority,
14734 HttpStreamRequest::Delegate* delegate)
14735 : priority_(priority),
[email protected]831e4a32013-11-14 02:14:4414736 delegate_(delegate),
14737 websocket_stream_create_helper_(NULL) {}
14738
14739 FakeStreamRequest(RequestPriority priority,
14740 HttpStreamRequest::Delegate* delegate,
14741 WebSocketHandshakeStreamBase::CreateHelper* create_helper)
14742 : priority_(priority),
14743 delegate_(delegate),
14744 websocket_stream_create_helper_(create_helper) {}
[email protected]e86839fd2013-08-14 18:29:0314745
dchengb03027d2014-10-21 12:00:2014746 ~FakeStreamRequest() override {}
[email protected]bf828982013-08-14 18:01:4714747
14748 RequestPriority priority() const { return priority_; }
14749
[email protected]831e4a32013-11-14 02:14:4414750 const WebSocketHandshakeStreamBase::CreateHelper*
14751 websocket_stream_create_helper() const {
14752 return websocket_stream_create_helper_;
14753 }
14754
[email protected]e86839fd2013-08-14 18:29:0314755 // Create a new FakeStream and pass it to the request's
14756 // delegate. Returns a weak pointer to the FakeStream.
14757 base::WeakPtr<FakeStream> FinishStreamRequest() {
14758 FakeStream* fake_stream = new FakeStream(priority_);
14759 // Do this before calling OnStreamReady() as OnStreamReady() may
14760 // immediately delete |fake_stream|.
14761 base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
14762 delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
14763 return weak_stream;
14764 }
14765
dchengb03027d2014-10-21 12:00:2014766 int RestartTunnelWithProxyAuth(const AuthCredentials& credentials) override {
[email protected]bf828982013-08-14 18:01:4714767 ADD_FAILURE();
14768 return ERR_UNEXPECTED;
14769 }
14770
dchengb03027d2014-10-21 12:00:2014771 LoadState GetLoadState() const override {
[email protected]bf828982013-08-14 18:01:4714772 ADD_FAILURE();
14773 return LoadState();
14774 }
14775
dchengb03027d2014-10-21 12:00:2014776 void SetPriority(RequestPriority priority) override { priority_ = priority; }
[email protected]bf828982013-08-14 18:01:4714777
dchengb03027d2014-10-21 12:00:2014778 bool was_npn_negotiated() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714779
dchengb03027d2014-10-21 12:00:2014780 NextProto protocol_negotiated() const override { return kProtoUnknown; }
[email protected]bf828982013-08-14 18:01:4714781
dchengb03027d2014-10-21 12:00:2014782 bool using_spdy() const override { return false; }
[email protected]bf828982013-08-14 18:01:4714783
ttuttle1f2d7e92015-04-28 16:17:4714784 const ConnectionAttempts& connection_attempts() const override {
14785 static ConnectionAttempts no_attempts;
14786 return no_attempts;
14787 }
14788
[email protected]bf828982013-08-14 18:01:4714789 private:
14790 RequestPriority priority_;
[email protected]e86839fd2013-08-14 18:29:0314791 HttpStreamRequest::Delegate* const delegate_;
[email protected]831e4a32013-11-14 02:14:4414792 WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
[email protected]bf828982013-08-14 18:01:4714793
14794 DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
14795};
14796
14797// Fake HttpStreamFactory that vends FakeStreamRequests.
14798class FakeStreamFactory : public HttpStreamFactory {
14799 public:
14800 FakeStreamFactory() {}
dchengb03027d2014-10-21 12:00:2014801 ~FakeStreamFactory() override {}
[email protected]bf828982013-08-14 18:01:4714802
14803 // Returns a WeakPtr<> to the last HttpStreamRequest returned by
14804 // RequestStream() (which may be NULL if it was destroyed already).
14805 base::WeakPtr<FakeStreamRequest> last_stream_request() {
14806 return last_stream_request_;
14807 }
14808
dchengb03027d2014-10-21 12:00:2014809 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
14810 RequestPriority priority,
14811 const SSLConfig& server_ssl_config,
14812 const SSLConfig& proxy_ssl_config,
14813 HttpStreamRequest::Delegate* delegate,
14814 const BoundNetLog& net_log) override {
[email protected]e86839fd2013-08-14 18:29:0314815 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
[email protected]bf828982013-08-14 18:01:4714816 last_stream_request_ = fake_request->AsWeakPtr();
14817 return fake_request;
14818 }
14819
xunjieli5749218c2016-03-22 16:43:0614820 HttpStreamRequest* RequestBidirectionalStreamImpl(
xunjieli11834f02015-12-22 04:27:0814821 const HttpRequestInfo& info,
14822 RequestPriority priority,
14823 const SSLConfig& server_ssl_config,
14824 const SSLConfig& proxy_ssl_config,
14825 HttpStreamRequest::Delegate* delegate,
14826 const BoundNetLog& net_log) override {
14827 NOTREACHED();
14828 return nullptr;
14829 }
14830
dchengb03027d2014-10-21 12:00:2014831 HttpStreamRequest* RequestWebSocketHandshakeStream(
[email protected]bf828982013-08-14 18:01:4714832 const HttpRequestInfo& info,
14833 RequestPriority priority,
14834 const SSLConfig& server_ssl_config,
14835 const SSLConfig& proxy_ssl_config,
14836 HttpStreamRequest::Delegate* delegate,
[email protected]467086b2013-11-12 08:19:4614837 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
mostynbba063d6032014-10-09 11:01:1314838 const BoundNetLog& net_log) override {
[email protected]831e4a32013-11-14 02:14:4414839 FakeStreamRequest* fake_request =
14840 new FakeStreamRequest(priority, delegate, create_helper);
14841 last_stream_request_ = fake_request->AsWeakPtr();
14842 return fake_request;
[email protected]bf828982013-08-14 18:01:4714843 }
14844
dchengb03027d2014-10-21 12:00:2014845 void PreconnectStreams(int num_streams,
nharper8cdb0fb2016-04-22 21:34:5914846 const HttpRequestInfo& info) override {
[email protected]bf828982013-08-14 18:01:4714847 ADD_FAILURE();
14848 }
14849
dchengb03027d2014-10-21 12:00:2014850 const HostMappingRules* GetHostMappingRules() const override {
[email protected]bf828982013-08-14 18:01:4714851 ADD_FAILURE();
14852 return NULL;
14853 }
14854
14855 private:
14856 base::WeakPtr<FakeStreamRequest> last_stream_request_;
14857
14858 DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
14859};
14860
Adam Rice425cf122015-01-19 06:18:2414861// TODO(ricea): Maybe unify this with the one in
14862// url_request_http_job_unittest.cc ?
14863class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
14864 public:
danakj1fd259a02016-04-16 03:17:0914865 FakeWebSocketBasicHandshakeStream(
14866 std::unique_ptr<ClientSocketHandle> connection,
14867 bool using_proxy)
Adam Rice425cf122015-01-19 06:18:2414868 : state_(connection.release(), using_proxy) {}
14869
14870 // Fake implementation of HttpStreamBase methods.
14871 // This ends up being quite "real" because this object has to really send data
14872 // on the mock socket. It might be easier to use the real implementation, but
14873 // the fact that the WebSocket code is not compiled on iOS makes that
14874 // difficult.
14875 int InitializeStream(const HttpRequestInfo* request_info,
14876 RequestPriority priority,
14877 const BoundNetLog& net_log,
14878 const CompletionCallback& callback) override {
14879 state_.Initialize(request_info, priority, net_log, callback);
14880 return OK;
14881 }
14882
14883 int SendRequest(const HttpRequestHeaders& request_headers,
14884 HttpResponseInfo* response,
14885 const CompletionCallback& callback) override {
14886 return parser()->SendRequest(state_.GenerateRequestLine(), request_headers,
14887 response, callback);
14888 }
14889
14890 int ReadResponseHeaders(const CompletionCallback& callback) override {
14891 return parser()->ReadResponseHeaders(callback);
14892 }
14893
14894 int ReadResponseBody(IOBuffer* buf,
14895 int buf_len,
14896 const CompletionCallback& callback) override {
14897 NOTREACHED();
14898 return ERR_IO_PENDING;
14899 }
14900
14901 void Close(bool not_reusable) override {
14902 if (parser())
14903 parser()->Close(true);
14904 }
14905
14906 bool IsResponseBodyComplete() const override {
14907 NOTREACHED();
14908 return false;
14909 }
14910
Adam Rice425cf122015-01-19 06:18:2414911 bool IsConnectionReused() const override {
14912 NOTREACHED();
14913 return false;
14914 }
14915 void SetConnectionReused() override { NOTREACHED(); }
14916
mmenkebd84c392015-09-02 14:12:3414917 bool CanReuseConnection() const override { return false; }
Adam Rice425cf122015-01-19 06:18:2414918
sclittle4de1bab92015-09-22 21:28:2414919 int64_t GetTotalReceivedBytes() const override {
Adam Rice425cf122015-01-19 06:18:2414920 NOTREACHED();
14921 return 0;
14922 }
14923
sclittlebe1ccf62015-09-02 19:40:3614924 int64_t GetTotalSentBytes() const override {
14925 NOTREACHED();
14926 return 0;
14927 }
14928
Adam Rice425cf122015-01-19 06:18:2414929 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
14930 NOTREACHED();
14931 return false;
14932 }
14933
Adam Ricecb76ac62015-02-20 05:33:2514934 void GetSSLInfo(SSLInfo* ssl_info) override {}
Adam Rice425cf122015-01-19 06:18:2414935
14936 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {
14937 NOTREACHED();
14938 }
14939
ttuttled9dbc652015-09-29 20:00:5914940 bool GetRemoteEndpoint(IPEndPoint* endpoint) override { return false; }
14941
nharperb7441ef2016-01-25 23:54:1414942 Error GetSignedEKMForTokenBinding(crypto::ECPrivateKey* key,
14943 std::vector<uint8_t>* out) override {
14944 ADD_FAILURE();
14945 return ERR_NOT_IMPLEMENTED;
14946 }
14947
Adam Rice425cf122015-01-19 06:18:2414948 void Drain(HttpNetworkSession* session) override { NOTREACHED(); }
14949
zhongyica364fbb2015-12-12 03:39:1214950 void PopulateNetErrorDetails(NetErrorDetails* details) override { return; }
14951
Adam Rice425cf122015-01-19 06:18:2414952 void SetPriority(RequestPriority priority) override { NOTREACHED(); }
14953
14954 UploadProgress GetUploadProgress() const override {
14955 NOTREACHED();
14956 return UploadProgress();
14957 }
14958
14959 HttpStream* RenewStreamForAuth() override {
14960 NOTREACHED();
14961 return nullptr;
14962 }
14963
14964 // Fake implementation of WebSocketHandshakeStreamBase method(s)
danakj1fd259a02016-04-16 03:17:0914965 std::unique_ptr<WebSocketStream> Upgrade() override {
Adam Rice425cf122015-01-19 06:18:2414966 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0914967 return std::unique_ptr<WebSocketStream>();
Adam Rice425cf122015-01-19 06:18:2414968 }
14969
14970 private:
14971 HttpStreamParser* parser() const { return state_.parser(); }
14972 HttpBasicState state_;
14973
14974 DISALLOW_COPY_AND_ASSIGN(FakeWebSocketBasicHandshakeStream);
14975};
14976
[email protected]831e4a32013-11-14 02:14:4414977// TODO(yhirano): Split this class out into a net/websockets file, if it is
14978// worth doing.
14979class FakeWebSocketStreamCreateHelper :
14980 public WebSocketHandshakeStreamBase::CreateHelper {
14981 public:
dchengb03027d2014-10-21 12:00:2014982 WebSocketHandshakeStreamBase* CreateBasicStream(
danakj1fd259a02016-04-16 03:17:0914983 std::unique_ptr<ClientSocketHandle> connection,
mostynbba063d6032014-10-09 11:01:1314984 bool using_proxy) override {
dchengc7eeda422015-12-26 03:56:4814985 return new FakeWebSocketBasicHandshakeStream(std::move(connection),
Adam Rice425cf122015-01-19 06:18:2414986 using_proxy);
[email protected]831e4a32013-11-14 02:14:4414987 }
14988
dchengb03027d2014-10-21 12:00:2014989 WebSocketHandshakeStreamBase* CreateSpdyStream(
[email protected]831e4a32013-11-14 02:14:4414990 const base::WeakPtr<SpdySession>& session,
mostynbba063d6032014-10-09 11:01:1314991 bool use_relative_url) override {
[email protected]831e4a32013-11-14 02:14:4414992 NOTREACHED();
14993 return NULL;
14994 };
14995
dchengb03027d2014-10-21 12:00:2014996 ~FakeWebSocketStreamCreateHelper() override {}
[email protected]831e4a32013-11-14 02:14:4414997
danakj1fd259a02016-04-16 03:17:0914998 virtual std::unique_ptr<WebSocketStream> Upgrade() {
[email protected]831e4a32013-11-14 02:14:4414999 NOTREACHED();
danakj1fd259a02016-04-16 03:17:0915000 return std::unique_ptr<WebSocketStream>();
[email protected]831e4a32013-11-14 02:14:4415001 }
15002};
15003
[email protected]bf828982013-08-14 18:01:4715004} // namespace
15005
15006// Make sure that HttpNetworkTransaction passes on its priority to its
15007// stream request on start.
15008TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
danakj1fd259a02016-04-16 03:17:0915009 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215010 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715011 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915012 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715013
dcheng48459ac22014-08-26 00:46:4115014 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715015
wezca1070932016-05-26 20:30:5215016 ASSERT_FALSE(fake_factory->last_stream_request());
[email protected]bf828982013-08-14 18:01:4715017
15018 HttpRequestInfo request;
15019 TestCompletionCallback callback;
15020 EXPECT_EQ(ERR_IO_PENDING,
15021 trans.Start(&request, callback.callback(), BoundNetLog()));
15022
15023 base::WeakPtr<FakeStreamRequest> fake_request =
15024 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215025 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715026 EXPECT_EQ(LOW, fake_request->priority());
15027}
15028
15029// Make sure that HttpNetworkTransaction passes on its priority
15030// updates to its stream request.
15031TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
danakj1fd259a02016-04-16 03:17:0915032 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215033 HttpNetworkSessionPeer peer(session.get());
[email protected]bf828982013-08-14 18:01:4715034 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915035 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]bf828982013-08-14 18:01:4715036
dcheng48459ac22014-08-26 00:46:4115037 HttpNetworkTransaction trans(LOW, session.get());
[email protected]bf828982013-08-14 18:01:4715038
15039 HttpRequestInfo request;
15040 TestCompletionCallback callback;
15041 EXPECT_EQ(ERR_IO_PENDING,
15042 trans.Start(&request, callback.callback(), BoundNetLog()));
15043
15044 base::WeakPtr<FakeStreamRequest> fake_request =
15045 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215046 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715047 EXPECT_EQ(LOW, fake_request->priority());
15048
15049 trans.SetPriority(LOWEST);
wezca1070932016-05-26 20:30:5215050 ASSERT_TRUE(fake_request);
[email protected]bf828982013-08-14 18:01:4715051 EXPECT_EQ(LOWEST, fake_request->priority());
15052}
15053
[email protected]e86839fd2013-08-14 18:29:0315054// Make sure that HttpNetworkTransaction passes on its priority
15055// updates to its stream.
15056TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
danakj1fd259a02016-04-16 03:17:0915057 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215058 HttpNetworkSessionPeer peer(session.get());
[email protected]e86839fd2013-08-14 18:29:0315059 FakeStreamFactory* fake_factory = new FakeStreamFactory();
danakj1fd259a02016-04-16 03:17:0915060 peer.SetHttpStreamFactory(std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]e86839fd2013-08-14 18:29:0315061
dcheng48459ac22014-08-26 00:46:4115062 HttpNetworkTransaction trans(LOW, session.get());
[email protected]e86839fd2013-08-14 18:29:0315063
15064 HttpRequestInfo request;
15065 TestCompletionCallback callback;
15066 EXPECT_EQ(ERR_IO_PENDING,
15067 trans.Start(&request, callback.callback(), BoundNetLog()));
15068
15069 base::WeakPtr<FakeStreamRequest> fake_request =
15070 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215071 ASSERT_TRUE(fake_request);
[email protected]e86839fd2013-08-14 18:29:0315072 base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
wezca1070932016-05-26 20:30:5215073 ASSERT_TRUE(fake_stream);
[email protected]e86839fd2013-08-14 18:29:0315074 EXPECT_EQ(LOW, fake_stream->priority());
15075
15076 trans.SetPriority(LOWEST);
15077 EXPECT_EQ(LOWEST, fake_stream->priority());
15078}
15079
[email protected]831e4a32013-11-14 02:14:4415080TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
15081 // The same logic needs to be tested for both ws: and wss: schemes, but this
15082 // test is already parameterised on NextProto, so it uses a loop to verify
15083 // that the different schemes work.
bncce36dca22015-04-21 22:11:2315084 std::string test_cases[] = {"ws://www.example.org/",
15085 "wss://www.example.org/"};
[email protected]831e4a32013-11-14 02:14:4415086 for (size_t i = 0; i < arraysize(test_cases); ++i) {
danakj1fd259a02016-04-16 03:17:0915087 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenkee65e7af2015-10-13 17:16:4215088 HttpNetworkSessionPeer peer(session.get());
[email protected]831e4a32013-11-14 02:14:4415089 FakeStreamFactory* fake_factory = new FakeStreamFactory();
15090 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
[email protected]0191b51c2013-11-18 10:55:2315091 peer.SetHttpStreamFactoryForWebSocket(
danakj1fd259a02016-04-16 03:17:0915092 std::unique_ptr<HttpStreamFactory>(fake_factory));
[email protected]831e4a32013-11-14 02:14:4415093
dcheng48459ac22014-08-26 00:46:4115094 HttpNetworkTransaction trans(LOW, session.get());
[email protected]831e4a32013-11-14 02:14:4415095 trans.SetWebSocketHandshakeStreamCreateHelper(
15096 &websocket_stream_create_helper);
15097
15098 HttpRequestInfo request;
15099 TestCompletionCallback callback;
15100 request.method = "GET";
15101 request.url = GURL(test_cases[i]);
15102
15103 EXPECT_EQ(ERR_IO_PENDING,
15104 trans.Start(&request, callback.callback(), BoundNetLog()));
15105
15106 base::WeakPtr<FakeStreamRequest> fake_request =
15107 fake_factory->last_stream_request();
wezca1070932016-05-26 20:30:5215108 ASSERT_TRUE(fake_request);
[email protected]831e4a32013-11-14 02:14:4415109 EXPECT_EQ(&websocket_stream_create_helper,
15110 fake_request->websocket_stream_create_helper());
15111 }
15112}
15113
[email protected]043b68c82013-08-22 23:41:5215114// Tests that when a used socket is returned to the SSL socket pool, it's closed
15115// if the transport socket pool is stalled on the global socket limit.
15116TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
15117 ClientSocketPoolManager::set_max_sockets_per_group(
15118 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15119 ClientSocketPoolManager::set_max_sockets_per_pool(
15120 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15121
15122 // Set up SSL request.
15123
15124 HttpRequestInfo ssl_request;
15125 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2315126 ssl_request.url = GURL("https://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215127
15128 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2315129 MockWrite(
15130 "GET / HTTP/1.1\r\n"
15131 "Host: www.example.org\r\n"
15132 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215133 };
15134 MockRead ssl_reads[] = {
15135 MockRead("HTTP/1.1 200 OK\r\n"),
15136 MockRead("Content-Length: 11\r\n\r\n"),
15137 MockRead("hello world"),
15138 MockRead(SYNCHRONOUS, OK),
15139 };
15140 StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
15141 ssl_writes, arraysize(ssl_writes));
15142 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15143
15144 SSLSocketDataProvider ssl(ASYNC, OK);
15145 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15146
15147 // Set up HTTP request.
15148
15149 HttpRequestInfo http_request;
15150 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315151 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215152
15153 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315154 MockWrite(
15155 "GET / HTTP/1.1\r\n"
15156 "Host: www.example.org\r\n"
15157 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215158 };
15159 MockRead http_reads[] = {
15160 MockRead("HTTP/1.1 200 OK\r\n"),
15161 MockRead("Content-Length: 7\r\n\r\n"),
15162 MockRead("falafel"),
15163 MockRead(SYNCHRONOUS, OK),
15164 };
15165 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15166 http_writes, arraysize(http_writes));
15167 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15168
danakj1fd259a02016-04-16 03:17:0915169 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215170
15171 // Start the SSL request.
15172 TestCompletionCallback ssl_callback;
danakj1fd259a02016-04-16 03:17:0915173 std::unique_ptr<HttpTransaction> ssl_trans(
[email protected]043b68c82013-08-22 23:41:5215174 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15175 ASSERT_EQ(ERR_IO_PENDING,
15176 ssl_trans->Start(&ssl_request, ssl_callback.callback(),
15177 BoundNetLog()));
15178
15179 // Start the HTTP request. Pool should stall.
15180 TestCompletionCallback http_callback;
danakj1fd259a02016-04-16 03:17:0915181 std::unique_ptr<HttpTransaction> http_trans(
[email protected]043b68c82013-08-22 23:41:5215182 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15183 ASSERT_EQ(ERR_IO_PENDING,
15184 http_trans->Start(&http_request, http_callback.callback(),
15185 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4115186 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215187
15188 // Wait for response from SSL request.
15189 ASSERT_EQ(OK, ssl_callback.WaitForResult());
15190 std::string response_data;
15191 ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
15192 EXPECT_EQ("hello world", response_data);
15193
15194 // The SSL socket should automatically be closed, so the HTTP request can
15195 // start.
dcheng48459ac22014-08-26 00:46:4115196 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
15197 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215198
15199 // The HTTP request can now complete.
15200 ASSERT_EQ(OK, http_callback.WaitForResult());
15201 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
15202 EXPECT_EQ("falafel", response_data);
15203
dcheng48459ac22014-08-26 00:46:4115204 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215205}
15206
15207// Tests that when a SSL connection is established but there's no corresponding
15208// request that needs it, the new socket is closed if the transport socket pool
15209// is stalled on the global socket limit.
15210TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
15211 ClientSocketPoolManager::set_max_sockets_per_group(
15212 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15213 ClientSocketPoolManager::set_max_sockets_per_pool(
15214 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15215
15216 // Set up an ssl request.
15217
15218 HttpRequestInfo ssl_request;
15219 ssl_request.method = "GET";
15220 ssl_request.url = GURL("https://www.foopy.com/");
15221
15222 // No data will be sent on the SSL socket.
15223 StaticSocketDataProvider ssl_data;
15224 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
15225
15226 SSLSocketDataProvider ssl(ASYNC, OK);
15227 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15228
15229 // Set up HTTP request.
15230
15231 HttpRequestInfo http_request;
15232 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2315233 http_request.url = GURL("http://www.example.org/");
[email protected]043b68c82013-08-22 23:41:5215234
15235 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2315236 MockWrite(
15237 "GET / HTTP/1.1\r\n"
15238 "Host: www.example.org\r\n"
15239 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5215240 };
15241 MockRead http_reads[] = {
15242 MockRead("HTTP/1.1 200 OK\r\n"),
15243 MockRead("Content-Length: 7\r\n\r\n"),
15244 MockRead("falafel"),
15245 MockRead(SYNCHRONOUS, OK),
15246 };
15247 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
15248 http_writes, arraysize(http_writes));
15249 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15250
danakj1fd259a02016-04-16 03:17:0915251 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5215252
15253 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
15254 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2915255 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5915256 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4115257 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215258
15259 // Start the HTTP request. Pool should stall.
15260 TestCompletionCallback http_callback;
danakj1fd259a02016-04-16 03:17:0915261 std::unique_ptr<HttpTransaction> http_trans(
[email protected]043b68c82013-08-22 23:41:5215262 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15263 ASSERT_EQ(ERR_IO_PENDING,
15264 http_trans->Start(&http_request, http_callback.callback(),
15265 BoundNetLog()));
dcheng48459ac22014-08-26 00:46:4115266 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5215267
15268 // The SSL connection will automatically be closed once the connection is
15269 // established, to let the HTTP request start.
15270 ASSERT_EQ(OK, http_callback.WaitForResult());
15271 std::string response_data;
15272 ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
15273 EXPECT_EQ("falafel", response_data);
15274
dcheng48459ac22014-08-26 00:46:4115275 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5215276}
15277
[email protected]02d74a02014-04-23 18:10:5415278TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915279 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215280 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915281 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215282 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415283
15284 HttpRequestInfo request;
15285 request.method = "POST";
15286 request.url = GURL("http://www.foo.com/");
15287 request.upload_data_stream = &upload_data_stream;
15288 request.load_flags = 0;
15289
danakj1fd259a02016-04-16 03:17:0915290 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15291 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115292 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415293 // Send headers successfully, but get an error while sending the body.
15294 MockWrite data_writes[] = {
15295 MockWrite("POST / HTTP/1.1\r\n"
15296 "Host: www.foo.com\r\n"
15297 "Connection: keep-alive\r\n"
15298 "Content-Length: 3\r\n\r\n"),
15299 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15300 };
15301
15302 MockRead data_reads[] = {
15303 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15304 MockRead("hello world"),
15305 MockRead(SYNCHRONOUS, OK),
15306 };
15307 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15308 arraysize(data_writes));
15309 session_deps_.socket_factory->AddSocketDataProvider(&data);
15310
15311 TestCompletionCallback callback;
15312
15313 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15314 EXPECT_EQ(ERR_IO_PENDING, rv);
15315
15316 rv = callback.WaitForResult();
15317 EXPECT_EQ(OK, rv);
15318
15319 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215320 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415321
wezca1070932016-05-26 20:30:5215322 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415323 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15324
15325 std::string response_data;
15326 rv = ReadTransaction(trans.get(), &response_data);
15327 EXPECT_EQ(OK, rv);
15328 EXPECT_EQ("hello world", response_data);
15329}
15330
15331// This test makes sure the retry logic doesn't trigger when reading an error
15332// response from a server that rejected a POST with a CONNECTION_RESET.
15333TEST_P(HttpNetworkTransactionTest,
15334 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0915335 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5415336 MockWrite data_writes[] = {
15337 MockWrite("GET / HTTP/1.1\r\n"
15338 "Host: www.foo.com\r\n"
15339 "Connection: keep-alive\r\n\r\n"),
15340 MockWrite("POST / HTTP/1.1\r\n"
15341 "Host: www.foo.com\r\n"
15342 "Connection: keep-alive\r\n"
15343 "Content-Length: 3\r\n\r\n"),
15344 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15345 };
15346
15347 MockRead data_reads[] = {
15348 MockRead("HTTP/1.1 200 Peachy\r\n"
15349 "Content-Length: 14\r\n\r\n"),
15350 MockRead("first response"),
15351 MockRead("HTTP/1.1 400 Not OK\r\n"
15352 "Content-Length: 15\r\n\r\n"),
15353 MockRead("second response"),
15354 MockRead(SYNCHRONOUS, OK),
15355 };
15356 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15357 arraysize(data_writes));
15358 session_deps_.socket_factory->AddSocketDataProvider(&data);
15359
15360 TestCompletionCallback callback;
15361 HttpRequestInfo request1;
15362 request1.method = "GET";
15363 request1.url = GURL("http://www.foo.com/");
15364 request1.load_flags = 0;
15365
danakj1fd259a02016-04-16 03:17:0915366 std::unique_ptr<HttpTransaction> trans1(
dcheng48459ac22014-08-26 00:46:4115367 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415368 int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
15369 EXPECT_EQ(ERR_IO_PENDING, rv);
15370
15371 rv = callback.WaitForResult();
15372 EXPECT_EQ(OK, rv);
15373
15374 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5215375 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5415376
wezca1070932016-05-26 20:30:5215377 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5415378 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
15379
15380 std::string response_data1;
15381 rv = ReadTransaction(trans1.get(), &response_data1);
15382 EXPECT_EQ(OK, rv);
15383 EXPECT_EQ("first response", response_data1);
15384 // Delete the transaction to release the socket back into the socket pool.
15385 trans1.reset();
15386
danakj1fd259a02016-04-16 03:17:0915387 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215388 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915389 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215390 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415391
15392 HttpRequestInfo request2;
15393 request2.method = "POST";
15394 request2.url = GURL("http://www.foo.com/");
15395 request2.upload_data_stream = &upload_data_stream;
15396 request2.load_flags = 0;
15397
danakj1fd259a02016-04-16 03:17:0915398 std::unique_ptr<HttpTransaction> trans2(
dcheng48459ac22014-08-26 00:46:4115399 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415400 rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
15401 EXPECT_EQ(ERR_IO_PENDING, rv);
15402
15403 rv = callback.WaitForResult();
15404 EXPECT_EQ(OK, rv);
15405
15406 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:5215407 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5415408
wezca1070932016-05-26 20:30:5215409 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5415410 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
15411
15412 std::string response_data2;
15413 rv = ReadTransaction(trans2.get(), &response_data2);
15414 EXPECT_EQ(OK, rv);
15415 EXPECT_EQ("second response", response_data2);
15416}
15417
15418TEST_P(HttpNetworkTransactionTest,
15419 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0915420 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215421 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915422 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215423 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415424
15425 HttpRequestInfo request;
15426 request.method = "POST";
15427 request.url = GURL("http://www.foo.com/");
15428 request.upload_data_stream = &upload_data_stream;
15429 request.load_flags = 0;
15430
danakj1fd259a02016-04-16 03:17:0915431 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15432 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115433 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415434 // Send headers successfully, but get an error while sending the body.
15435 MockWrite data_writes[] = {
15436 MockWrite("POST / HTTP/1.1\r\n"
15437 "Host: www.foo.com\r\n"
15438 "Connection: keep-alive\r\n"
15439 "Content-Length: 3\r\n\r\n"
15440 "fo"),
15441 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15442 };
15443
15444 MockRead data_reads[] = {
15445 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15446 MockRead("hello world"),
15447 MockRead(SYNCHRONOUS, OK),
15448 };
15449 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15450 arraysize(data_writes));
15451 session_deps_.socket_factory->AddSocketDataProvider(&data);
15452
15453 TestCompletionCallback callback;
15454
15455 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15456 EXPECT_EQ(ERR_IO_PENDING, rv);
15457
15458 rv = callback.WaitForResult();
15459 EXPECT_EQ(OK, rv);
15460
15461 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215462 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415463
wezca1070932016-05-26 20:30:5215464 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415465 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15466
15467 std::string response_data;
15468 rv = ReadTransaction(trans.get(), &response_data);
15469 EXPECT_EQ(OK, rv);
15470 EXPECT_EQ("hello world", response_data);
15471}
15472
15473// This tests the more common case than the previous test, where headers and
15474// body are not merged into a single request.
15475TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0715476 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5415477
15478 HttpRequestInfo request;
15479 request.method = "POST";
15480 request.url = GURL("http://www.foo.com/");
15481 request.upload_data_stream = &upload_data_stream;
15482 request.load_flags = 0;
15483
danakj1fd259a02016-04-16 03:17:0915484 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15485 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115486 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415487 // Send headers successfully, but get an error while sending the body.
15488 MockWrite data_writes[] = {
15489 MockWrite("POST / HTTP/1.1\r\n"
15490 "Host: www.foo.com\r\n"
15491 "Connection: keep-alive\r\n"
15492 "Transfer-Encoding: chunked\r\n\r\n"),
15493 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15494 };
15495
15496 MockRead data_reads[] = {
15497 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15498 MockRead("hello world"),
15499 MockRead(SYNCHRONOUS, OK),
15500 };
15501 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15502 arraysize(data_writes));
15503 session_deps_.socket_factory->AddSocketDataProvider(&data);
15504
15505 TestCompletionCallback callback;
15506
15507 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15508 EXPECT_EQ(ERR_IO_PENDING, rv);
15509 // Make sure the headers are sent before adding a chunk. This ensures that
15510 // they can't be merged with the body in a single send. Not currently
15511 // necessary since a chunked body is never merged with headers, but this makes
15512 // the test more future proof.
15513 base::RunLoop().RunUntilIdle();
15514
mmenkecbc2b712014-10-09 20:29:0715515 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5415516
15517 rv = callback.WaitForResult();
15518 EXPECT_EQ(OK, rv);
15519
15520 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215521 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415522
wezca1070932016-05-26 20:30:5215523 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415524 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15525
15526 std::string response_data;
15527 rv = ReadTransaction(trans.get(), &response_data);
15528 EXPECT_EQ(OK, rv);
15529 EXPECT_EQ("hello world", response_data);
15530}
15531
15532TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915533 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215534 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915535 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215536 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415537
15538 HttpRequestInfo request;
15539 request.method = "POST";
15540 request.url = GURL("http://www.foo.com/");
15541 request.upload_data_stream = &upload_data_stream;
15542 request.load_flags = 0;
15543
danakj1fd259a02016-04-16 03:17:0915544 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15545 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115546 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415547
15548 MockWrite data_writes[] = {
15549 MockWrite("POST / HTTP/1.1\r\n"
15550 "Host: www.foo.com\r\n"
15551 "Connection: keep-alive\r\n"
15552 "Content-Length: 3\r\n\r\n"),
15553 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15554 };
15555
15556 MockRead data_reads[] = {
15557 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15558 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
15559 MockRead("hello world"),
15560 MockRead(SYNCHRONOUS, OK),
15561 };
15562 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15563 arraysize(data_writes));
15564 session_deps_.socket_factory->AddSocketDataProvider(&data);
15565
15566 TestCompletionCallback callback;
15567
15568 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15569 EXPECT_EQ(ERR_IO_PENDING, rv);
15570
15571 rv = callback.WaitForResult();
15572 EXPECT_EQ(OK, rv);
15573
15574 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215575 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5415576
wezca1070932016-05-26 20:30:5215577 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5415578 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
15579
15580 std::string response_data;
15581 rv = ReadTransaction(trans.get(), &response_data);
15582 EXPECT_EQ(OK, rv);
15583 EXPECT_EQ("hello world", response_data);
15584}
15585
15586TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915587 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215588 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915589 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215590 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415591
15592 HttpRequestInfo request;
15593 request.method = "POST";
15594 request.url = GURL("http://www.foo.com/");
15595 request.upload_data_stream = &upload_data_stream;
15596 request.load_flags = 0;
15597
danakj1fd259a02016-04-16 03:17:0915598 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15599 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115600 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415601 // Send headers successfully, but get an error while sending the body.
15602 MockWrite data_writes[] = {
15603 MockWrite("POST / HTTP/1.1\r\n"
15604 "Host: www.foo.com\r\n"
15605 "Connection: keep-alive\r\n"
15606 "Content-Length: 3\r\n\r\n"),
15607 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15608 };
15609
15610 MockRead data_reads[] = {
15611 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
15612 MockRead("hello world"),
15613 MockRead(SYNCHRONOUS, OK),
15614 };
15615 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15616 arraysize(data_writes));
15617 session_deps_.socket_factory->AddSocketDataProvider(&data);
15618
15619 TestCompletionCallback callback;
15620
15621 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15622 EXPECT_EQ(ERR_IO_PENDING, rv);
15623
15624 rv = callback.WaitForResult();
15625 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415626}
15627
15628TEST_P(HttpNetworkTransactionTest,
15629 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0915630 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215631 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915632 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215633 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415634
15635 HttpRequestInfo request;
15636 request.method = "POST";
15637 request.url = GURL("http://www.foo.com/");
15638 request.upload_data_stream = &upload_data_stream;
15639 request.load_flags = 0;
15640
danakj1fd259a02016-04-16 03:17:0915641 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15642 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115643 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415644 // Send headers successfully, but get an error while sending the body.
15645 MockWrite data_writes[] = {
15646 MockWrite("POST / HTTP/1.1\r\n"
15647 "Host: www.foo.com\r\n"
15648 "Connection: keep-alive\r\n"
15649 "Content-Length: 3\r\n\r\n"),
15650 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15651 };
15652
15653 MockRead data_reads[] = {
15654 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
15655 MockRead("HTTP/1.0 302 Redirect\r\n"),
15656 MockRead("Location: http://somewhere-else.com/\r\n"),
15657 MockRead("Content-Length: 0\r\n\r\n"),
15658 MockRead(SYNCHRONOUS, OK),
15659 };
15660 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15661 arraysize(data_writes));
15662 session_deps_.socket_factory->AddSocketDataProvider(&data);
15663
15664 TestCompletionCallback callback;
15665
15666 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15667 EXPECT_EQ(ERR_IO_PENDING, rv);
15668
15669 rv = callback.WaitForResult();
15670 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415671}
15672
15673TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0915674 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215675 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915676 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215677 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415678
15679 HttpRequestInfo request;
15680 request.method = "POST";
15681 request.url = GURL("http://www.foo.com/");
15682 request.upload_data_stream = &upload_data_stream;
15683 request.load_flags = 0;
15684
danakj1fd259a02016-04-16 03:17:0915685 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15686 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115687 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415688 // Send headers successfully, but get an error while sending the body.
15689 MockWrite data_writes[] = {
15690 MockWrite("POST / HTTP/1.1\r\n"
15691 "Host: www.foo.com\r\n"
15692 "Connection: keep-alive\r\n"
15693 "Content-Length: 3\r\n\r\n"),
15694 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15695 };
15696
15697 MockRead data_reads[] = {
15698 MockRead("HTTP 0.9 rocks!"),
15699 MockRead(SYNCHRONOUS, OK),
15700 };
15701 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15702 arraysize(data_writes));
15703 session_deps_.socket_factory->AddSocketDataProvider(&data);
15704
15705 TestCompletionCallback callback;
15706
15707 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15708 EXPECT_EQ(ERR_IO_PENDING, rv);
15709
15710 rv = callback.WaitForResult();
15711 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415712}
15713
15714TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0915715 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215716 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915717 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215718 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5415719
15720 HttpRequestInfo request;
15721 request.method = "POST";
15722 request.url = GURL("http://www.foo.com/");
15723 request.upload_data_stream = &upload_data_stream;
15724 request.load_flags = 0;
15725
danakj1fd259a02016-04-16 03:17:0915726 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15727 std::unique_ptr<HttpTransaction> trans(
dcheng48459ac22014-08-26 00:46:4115728 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
[email protected]02d74a02014-04-23 18:10:5415729 // Send headers successfully, but get an error while sending the body.
15730 MockWrite data_writes[] = {
15731 MockWrite("POST / HTTP/1.1\r\n"
15732 "Host: www.foo.com\r\n"
15733 "Connection: keep-alive\r\n"
15734 "Content-Length: 3\r\n\r\n"),
15735 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15736 };
15737
15738 MockRead data_reads[] = {
15739 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
15740 MockRead(SYNCHRONOUS, OK),
15741 };
15742 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15743 arraysize(data_writes));
15744 session_deps_.socket_factory->AddSocketDataProvider(&data);
15745
15746 TestCompletionCallback callback;
15747
15748 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15749 EXPECT_EQ(ERR_IO_PENDING, rv);
15750
15751 rv = callback.WaitForResult();
15752 EXPECT_EQ(ERR_CONNECTION_RESET, rv);
[email protected]02d74a02014-04-23 18:10:5415753}
15754
Adam Rice425cf122015-01-19 06:18:2415755// Verify that proxy headers are not sent to the destination server when
15756// establishing a tunnel for a secure WebSocket connection.
15757TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
15758 HttpRequestInfo request;
15759 request.method = "GET";
bncce36dca22015-04-21 22:11:2315760 request.url = GURL("wss://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415761 AddWebSocketHeaders(&request.extra_headers);
15762
15763 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315764 session_deps_.proxy_service =
15765 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415766
danakj1fd259a02016-04-16 03:17:0915767 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415768
15769 // Since a proxy is configured, try to establish a tunnel.
15770 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1715771 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15772 "Host: www.example.org:443\r\n"
15773 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415774
15775 // After calling trans->RestartWithAuth(), this is the request we should
15776 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1715777 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
15778 "Host: www.example.org:443\r\n"
15779 "Proxy-Connection: keep-alive\r\n"
15780 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415781
rsleevidb16bb02015-11-12 23:47:1715782 MockWrite("GET / HTTP/1.1\r\n"
15783 "Host: www.example.org\r\n"
15784 "Connection: Upgrade\r\n"
15785 "Upgrade: websocket\r\n"
15786 "Origin: http://www.example.org\r\n"
15787 "Sec-WebSocket-Version: 13\r\n"
15788 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415789 };
15790
15791 // The proxy responds to the connect with a 407, using a persistent
15792 // connection.
15793 MockRead data_reads[] = {
15794 // No credentials.
15795 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
15796 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
mmenkee71e15332015-10-07 16:39:5415797 MockRead("Content-Length: 0\r\n"),
15798 MockRead("Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2415799
15800 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15801
15802 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15803 MockRead("Upgrade: websocket\r\n"),
15804 MockRead("Connection: Upgrade\r\n"),
15805 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15806 };
15807
15808 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15809 arraysize(data_writes));
15810 session_deps_.socket_factory->AddSocketDataProvider(&data);
15811 SSLSocketDataProvider ssl(ASYNC, OK);
15812 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15813
danakj1fd259a02016-04-16 03:17:0915814 std::unique_ptr<HttpTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2415815 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15816 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15817 trans->SetWebSocketHandshakeStreamCreateHelper(
15818 &websocket_stream_create_helper);
15819
15820 {
15821 TestCompletionCallback callback;
15822
15823 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15824 EXPECT_EQ(ERR_IO_PENDING, rv);
15825
15826 rv = callback.WaitForResult();
15827 EXPECT_EQ(OK, rv);
15828 }
15829
15830 const HttpResponseInfo* response = trans->GetResponseInfo();
15831 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215832 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415833 EXPECT_EQ(407, response->headers->response_code());
15834
15835 {
15836 TestCompletionCallback callback;
15837
15838 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
15839 callback.callback());
15840 EXPECT_EQ(ERR_IO_PENDING, rv);
15841
15842 rv = callback.WaitForResult();
15843 EXPECT_EQ(OK, rv);
15844 }
15845
15846 response = trans->GetResponseInfo();
15847 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215848 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415849
15850 EXPECT_EQ(101, response->headers->response_code());
15851
15852 trans.reset();
15853 session->CloseAllConnections();
15854}
15855
15856// Verify that proxy headers are not sent to the destination server when
15857// establishing a tunnel for an insecure WebSocket connection.
15858// This requires the authentication info to be injected into the auth cache
15859// due to crbug.com/395064
15860// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
15861TEST_P(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
15862 HttpRequestInfo request;
15863 request.method = "GET";
bncce36dca22015-04-21 22:11:2315864 request.url = GURL("ws://www.example.org/");
Adam Rice425cf122015-01-19 06:18:2415865 AddWebSocketHeaders(&request.extra_headers);
15866
15867 // Configure against proxy server "myproxy:70".
rdsmith82957ad2015-09-16 19:42:0315868 session_deps_.proxy_service =
15869 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70");
Adam Rice425cf122015-01-19 06:18:2415870
danakj1fd259a02016-04-16 03:17:0915871 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2415872
15873 MockWrite data_writes[] = {
15874 // Try to establish a tunnel for the WebSocket connection, with
15875 // credentials. Because WebSockets have a separate set of socket pools,
15876 // they cannot and will not use the same TCP/IP connection as the
15877 // preflight HTTP request.
15878 MockWrite(
bncce36dca22015-04-21 22:11:2315879 "CONNECT www.example.org:80 HTTP/1.1\r\n"
15880 "Host: www.example.org:80\r\n"
Adam Rice425cf122015-01-19 06:18:2415881 "Proxy-Connection: keep-alive\r\n"
15882 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
15883
15884 MockWrite(
15885 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315886 "Host: www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415887 "Connection: Upgrade\r\n"
15888 "Upgrade: websocket\r\n"
bncce36dca22015-04-21 22:11:2315889 "Origin: http://www.example.org\r\n"
Adam Rice425cf122015-01-19 06:18:2415890 "Sec-WebSocket-Version: 13\r\n"
15891 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n\r\n"),
15892 };
15893
15894 MockRead data_reads[] = {
15895 // HTTP CONNECT with credentials.
15896 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
15897
15898 // WebSocket connection established inside tunnel.
15899 MockRead("HTTP/1.1 101 Switching Protocols\r\n"),
15900 MockRead("Upgrade: websocket\r\n"),
15901 MockRead("Connection: Upgrade\r\n"),
15902 MockRead("Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n"),
15903 };
15904
15905 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15906 arraysize(data_writes));
15907 session_deps_.socket_factory->AddSocketDataProvider(&data);
15908
15909 session->http_auth_cache()->Add(
15910 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
15911 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
15912
danakj1fd259a02016-04-16 03:17:0915913 std::unique_ptr<HttpTransaction> trans(
Adam Rice425cf122015-01-19 06:18:2415914 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15915 FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
15916 trans->SetWebSocketHandshakeStreamCreateHelper(
15917 &websocket_stream_create_helper);
15918
15919 TestCompletionCallback callback;
15920
15921 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
15922 EXPECT_EQ(ERR_IO_PENDING, rv);
15923
15924 rv = callback.WaitForResult();
15925 EXPECT_EQ(OK, rv);
15926
15927 const HttpResponseInfo* response = trans->GetResponseInfo();
15928 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5215929 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2415930
15931 EXPECT_EQ(101, response->headers->response_code());
15932
15933 trans.reset();
15934 session->CloseAllConnections();
15935}
15936
sclittlefb249892015-09-10 21:33:2215937TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0915938 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215939 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915940 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215941 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2215942
15943 HttpRequestInfo request;
15944 request.method = "POST";
15945 request.url = GURL("http://www.foo.com/");
15946 request.upload_data_stream = &upload_data_stream;
15947
danakj1fd259a02016-04-16 03:17:0915948 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15949 std::unique_ptr<HttpTransaction> trans(
sclittlefb249892015-09-10 21:33:2215950 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15951 MockWrite data_writes[] = {
15952 MockWrite("POST / HTTP/1.1\r\n"
15953 "Host: www.foo.com\r\n"
15954 "Connection: keep-alive\r\n"
15955 "Content-Length: 3\r\n\r\n"),
15956 MockWrite("foo"),
15957 };
15958
15959 MockRead data_reads[] = {
15960 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
15961 MockRead(SYNCHRONOUS, OK),
15962 };
15963 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
15964 arraysize(data_writes));
15965 session_deps_.socket_factory->AddSocketDataProvider(&data);
15966
15967 TestCompletionCallback callback;
15968
15969 EXPECT_EQ(ERR_IO_PENDING,
15970 trans->Start(&request, callback.callback(), BoundNetLog()));
15971 EXPECT_EQ(OK, callback.WaitForResult());
15972
15973 std::string response_data;
15974 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
15975
15976 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
15977 trans->GetTotalSentBytes());
15978 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
15979 trans->GetTotalReceivedBytes());
15980}
15981
15982TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0915983 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2215984 element_readers.push_back(
danakj1fd259a02016-04-16 03:17:0915985 base::WrapUnique(new UploadBytesElementReader("foo", 3)));
olli.raula6df48b2a2015-11-26 07:40:2215986 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2215987
15988 HttpRequestInfo request;
15989 request.method = "POST";
15990 request.url = GURL("http://www.foo.com/");
15991 request.upload_data_stream = &upload_data_stream;
15992
danakj1fd259a02016-04-16 03:17:0915993 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15994 std::unique_ptr<HttpTransaction> trans(
sclittlefb249892015-09-10 21:33:2215995 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
15996 MockWrite data_writes[] = {
15997 MockWrite("POST / HTTP/1.1\r\n"
15998 "Host: www.foo.com\r\n"
15999 "Connection: keep-alive\r\n"
16000 "Content-Length: 3\r\n\r\n"),
16001 MockWrite("foo"),
16002 };
16003
16004 MockRead data_reads[] = {
16005 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
16006 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16007 MockRead(SYNCHRONOUS, OK),
16008 };
16009 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16010 arraysize(data_writes));
16011 session_deps_.socket_factory->AddSocketDataProvider(&data);
16012
16013 TestCompletionCallback callback;
16014
16015 EXPECT_EQ(ERR_IO_PENDING,
16016 trans->Start(&request, callback.callback(), BoundNetLog()));
16017 EXPECT_EQ(OK, callback.WaitForResult());
16018
16019 std::string response_data;
16020 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
16021
16022 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
16023 trans->GetTotalSentBytes());
16024 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
16025 trans->GetTotalReceivedBytes());
16026}
16027
16028TEST_P(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2216029 ChunkedUploadDataStream upload_data_stream(0);
16030
16031 HttpRequestInfo request;
16032 request.method = "POST";
16033 request.url = GURL("http://www.foo.com/");
16034 request.upload_data_stream = &upload_data_stream;
16035
danakj1fd259a02016-04-16 03:17:0916036 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
16037 std::unique_ptr<HttpTransaction> trans(
sclittlefb249892015-09-10 21:33:2216038 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
16039 // Send headers successfully, but get an error while sending the body.
16040 MockWrite data_writes[] = {
16041 MockWrite("POST / HTTP/1.1\r\n"
16042 "Host: www.foo.com\r\n"
16043 "Connection: keep-alive\r\n"
16044 "Transfer-Encoding: chunked\r\n\r\n"),
16045 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
16046 };
16047
16048 MockRead data_reads[] = {
16049 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
16050 MockRead(SYNCHRONOUS, OK),
16051 };
16052 StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
16053 arraysize(data_writes));
16054 session_deps_.socket_factory->AddSocketDataProvider(&data);
16055
16056 TestCompletionCallback callback;
16057
16058 EXPECT_EQ(ERR_IO_PENDING,
16059 trans->Start(&request, callback.callback(), BoundNetLog()));
16060
16061 base::RunLoop().RunUntilIdle();
16062 upload_data_stream.AppendData("f", 1, false);
16063
16064 base::RunLoop().RunUntilIdle();
16065 upload_data_stream.AppendData("oo", 2, true);
16066
16067 EXPECT_EQ(OK, callback.WaitForResult());
16068
16069 std::string response_data;
16070 EXPECT_EQ(OK, ReadTransaction(trans.get(), &response_data));
16071
16072 EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)),
16073 trans->GetTotalSentBytes());
16074 EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)),
16075 trans->GetTotalReceivedBytes());
16076}
16077
bncf4588402015-11-24 13:33:1816078TEST_P(HttpNetworkTransactionTest, EnableNPN) {
bncf4588402015-11-24 13:33:1816079 session_deps_.enable_npn = true;
16080
danakj1fd259a02016-04-16 03:17:0916081 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncf4588402015-11-24 13:33:1816082 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
nharper8cdb0fb2016-04-22 21:34:5916083 HttpRequestInfo request;
16084 TestCompletionCallback callback;
16085 EXPECT_EQ(ERR_IO_PENDING,
16086 trans.Start(&request, callback.callback(), BoundNetLog()));
bncf4588402015-11-24 13:33:1816087
16088 EXPECT_THAT(trans.server_ssl_config_.alpn_protos,
16089 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
16090 EXPECT_THAT(trans.server_ssl_config_.npn_protos,
16091 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
16092}
16093
16094TEST_P(HttpNetworkTransactionTest, DisableNPN) {
bncf4588402015-11-24 13:33:1816095 session_deps_.enable_npn = false;
16096
danakj1fd259a02016-04-16 03:17:0916097 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bncf4588402015-11-24 13:33:1816098 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
nharper8cdb0fb2016-04-22 21:34:5916099 HttpRequestInfo request;
16100 TestCompletionCallback callback;
16101 EXPECT_EQ(ERR_IO_PENDING,
16102 trans.Start(&request, callback.callback(), BoundNetLog()));
bncf4588402015-11-24 13:33:1816103
16104 EXPECT_THAT(trans.server_ssl_config_.alpn_protos,
16105 testing::ElementsAre(kProtoHTTP2, kProtoSPDY31, kProtoHTTP11));
16106 EXPECT_TRUE(trans.server_ssl_config_.npn_protos.empty());
16107}
16108
nharperb7441ef2016-01-25 23:54:1416109#if !defined(OS_IOS)
16110TEST_P(HttpNetworkTransactionTest, TokenBindingSpdy) {
16111 const std::string https_url = "https://www.example.com";
16112 HttpRequestInfo request;
16113 request.url = GURL(https_url);
16114 request.method = "GET";
16115
16116 SSLSocketDataProvider ssl(ASYNC, OK);
16117 ssl.token_binding_negotiated = true;
16118 ssl.token_binding_key_param = TB_PARAM_ECDSAP256;
16119 ssl.SetNextProto(GetProtocol());
16120 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16121
danakj1fd259a02016-04-16 03:17:0916122 std::unique_ptr<SpdySerializedFrame> resp(
nharperb7441ef2016-01-25 23:54:1416123 spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
danakj1fd259a02016-04-16 03:17:0916124 std::unique_ptr<SpdySerializedFrame> body(
bncb03b1092016-04-06 11:19:5516125 spdy_util_.ConstructSpdyBodyFrame(1, true));
nharperb7441ef2016-01-25 23:54:1416126 MockRead reads[] = {CreateMockRead(*resp), CreateMockRead(*body),
16127 MockRead(ASYNC, ERR_IO_PENDING)};
16128 StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
16129 session_deps_.socket_factory->AddSocketDataProvider(&data);
16130 session_deps_.channel_id_service.reset(new ChannelIDService(
16131 new DefaultChannelIDStore(nullptr), base::ThreadTaskRunnerHandle::Get()));
danakj1fd259a02016-04-16 03:17:0916132 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
nharperb7441ef2016-01-25 23:54:1416133
16134 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
16135 TestCompletionCallback callback;
16136 EXPECT_EQ(ERR_IO_PENDING,
16137 trans.Start(&request, callback.callback(), BoundNetLog()));
fdoray92e35a72016-06-10 15:54:5516138 base::RunLoop().RunUntilIdle();
nharperb7441ef2016-01-25 23:54:1416139
16140 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
16141 HttpRequestHeaders headers;
16142 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
16143 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
16144}
16145#endif // !defined(OS_IOS)
16146
[email protected]89ceba9a2009-03-21 03:46:0616147} // namespace net