blob: 7460aae49ea912822e6b4dde9b0cd028e97c6284 [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>
rdsmith1d343be52016-10-21 20:37:5012#include <set>
[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"
Bence Békyd74f4382018-02-20 18:26:1926#include "base/strings/string_piece.h"
[email protected]125ef482013-06-11 18:32:4727#include "base/strings/string_util.h"
[email protected]750b2f3c2013-06-07 18:41:0528#include "base/strings/utf_string_conversions.h"
Douglas Creager3cb042052018-11-06 23:08:5229#include "base/test/metrics/histogram_tester.h"
Douglas Creager134b52e2018-11-09 18:00:1430#include "base/test/simple_test_clock.h"
31#include "base/test/simple_test_tick_clock.h"
[email protected]f36a8132011-09-02 18:36:3332#include "base/test/test_file_util.h"
gabf767595f2016-05-11 18:50:3533#include "base/threading/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3534#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0735#include "net/base/chunked_upload_data_stream.h"
Bence Békya25e3f72018-02-13 21:13:3936#include "net/base/completion_once_callback.h"
mmenkecbc2b712014-10-09 20:29:0737#include "net/base/elements_upload_data_stream.h"
[email protected]58e32bb2013-01-21 18:23:2538#include "net/base/load_timing_info.h"
39#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2440#include "net/base/net_errors.h"
tbansal28e68f82016-02-04 02:56:1541#include "net/base/proxy_delegate.h"
Lily Houghton582d4622018-01-22 22:43:4042#include "net/base/proxy_server.h"
[email protected]ac790b42009-12-02 04:31:3143#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5244#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1545#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0646#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2147#include "net/base/upload_file_element_reader.h"
Bence Béky230ac612017-08-30 19:17:0848#include "net/cert/cert_status_flags.h"
[email protected]6e7845ae2013-03-29 21:48:1149#include "net/cert/mock_cert_verifier.h"
[email protected]bc71b8772013-04-10 20:55:1650#include "net/dns/host_cache.h"
[email protected]f2cb3cf2013-03-21 01:40:5351#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2452#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1253#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0054#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2955#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1956#include "net/http/http_auth_scheme.h"
[email protected]0877e3d2009-10-17 22:29:5757#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5258#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5659#include "net/http/http_network_session_peer.h"
Adam Rice425cf122015-01-19 06:18:2460#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1361#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5362#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5763#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3864#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1965#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0766#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0067#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1968#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5169#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4670#include "net/log/test_net_log_entry.h"
71#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4072#include "net/proxy_resolution/mock_proxy_resolver.h"
73#include "net/proxy_resolution/proxy_config_service_fixed.h"
74#include "net/proxy_resolution/proxy_info.h"
Lily Houghtonffe89daa02018-03-09 18:30:0375#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4076#include "net/proxy_resolution/proxy_resolver.h"
77#include "net/proxy_resolution/proxy_resolver_factory.h"
[email protected]f7984fc62009-06-22 23:26:4478#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1579#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0380#include "net/socket/client_socket_pool_manager.h"
ttuttle1f2d7e92015-04-28 16:17:4781#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0282#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0783#include "net/socket/next_proto.h"
Paul Jensena457017a2018-01-19 23:52:0484#include "net/socket/socket_tag.h"
[email protected]f7984fc62009-06-22 23:26:4485#include "net/socket/socket_test_util.h"
86#include "net/socket/ssl_client_socket.h"
Bence Béky94658bf2018-05-11 19:22:5887#include "net/spdy/spdy_session.h"
88#include "net/spdy/spdy_session_pool.h"
89#include "net/spdy/spdy_test_util_common.h"
nharperb7441ef2016-01-25 23:54:1490#include "net/ssl/default_channel_id_store.h"
[email protected]536fd0b2013-03-14 17:41:5791#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:0392#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:5793#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:5494#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:1195#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0196#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4397#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0198#include "net/test/test_with_scoped_task_environment.h"
Ryan Hamilton2e003eea2018-05-02 00:24:2999#include "net/third_party/spdy/core/spdy_framer.h"
[email protected]baee31a2018-01-18 06:10:23100#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]831e4a32013-11-14 02:14:44101#include "net/websockets/websocket_handshake_stream_base.h"
Bence Békydca6bd92018-01-30 13:43:06102#include "net/websockets/websocket_test_util.h"
bncf4588402015-11-24 13:33:18103#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52104#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15105#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27106#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52107
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37108#if defined(NTLM_PORTABLE)
109#include "base/base64.h"
110#include "net/ntlm/ntlm_test_data.h"
111#endif
112
Douglas Creager3cb042052018-11-06 23:08:52113#if BUILDFLAG(ENABLE_REPORTING)
114#include "net/network_error_logging/network_error_logging_service.h"
115#include "net/network_error_logging/network_error_logging_test_util.h"
Douglas Creager134b52e2018-11-09 18:00:14116#include "net/reporting/reporting_cache.h"
117#include "net/reporting/reporting_client.h"
118#include "net/reporting/reporting_header_parser.h"
119#include "net/reporting/reporting_service.h"
120#include "net/reporting/reporting_test_util.h"
Douglas Creager3cb042052018-11-06 23:08:52121#endif // BUILDFLAG(ENABLE_REPORTING)
122
robpercival214763f2016-07-01 23:27:01123using net::test::IsError;
124using net::test::IsOk;
125
[email protected]ad65a3e2013-12-25 18:18:01126using base::ASCIIToUTF16;
127
initial.commit586acc5fe2008-07-26 22:42:52128//-----------------------------------------------------------------------------
129
ttuttle859dc7a2015-04-23 19:42:29130namespace net {
131
[email protected]13c8a092010-07-29 06:15:44132namespace {
133
[email protected]42cba2fb2013-03-29 19:58:57134const base::string16 kBar(ASCIIToUTF16("bar"));
135const base::string16 kBar2(ASCIIToUTF16("bar2"));
136const base::string16 kBar3(ASCIIToUTF16("bar3"));
137const base::string16 kBaz(ASCIIToUTF16("baz"));
138const base::string16 kFirst(ASCIIToUTF16("first"));
139const base::string16 kFoo(ASCIIToUTF16("foo"));
140const base::string16 kFoo2(ASCIIToUTF16("foo2"));
141const base::string16 kFoo3(ASCIIToUTF16("foo3"));
142const base::string16 kFou(ASCIIToUTF16("fou"));
143const base::string16 kSecond(ASCIIToUTF16("second"));
[email protected]42cba2fb2013-03-29 19:58:57144const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44145
bnc2df4b522016-07-08 18:17:43146const char kAlternativeServiceHttpHeader[] =
147 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
148
ttuttle859dc7a2015-04-23 19:42:29149int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
150 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
151 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02152}
153
ttuttle859dc7a2015-04-23 19:42:29154int GetIdleSocketCountInSSLSocketPool(HttpNetworkSession* session) {
155 return session->GetSSLSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
156 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02157}
158
ttuttle859dc7a2015-04-23 19:42:29159bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
160 return session->GetTransportSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL)
161 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52162}
163
[email protected]f3da152d2012-06-02 01:00:57164// Takes in a Value created from a NetLogHttpResponseParameter, and returns
165// a JSONified list of headers as a single string. Uses single quotes instead
166// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27167bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57168 if (!params)
169 return false;
[email protected]ea5ef4c2013-06-13 22:50:27170 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57171 if (!params->GetList("headers", &header_list))
172 return false;
173 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34174 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28175 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57176 return true;
177}
178
[email protected]029c83b62013-01-24 05:28:20179// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
180// used.
ttuttle859dc7a2015-04-23 19:42:29181void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20182 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19183 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25184
[email protected]029c83b62013-01-24 05:28:20185 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
186 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
187
ttuttle859dc7a2015-04-23 19:42:29188 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20189 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25190
191 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25192
[email protected]3b23a222013-05-15 21:33:25193 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25194 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
195 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25196 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25197}
198
[email protected]029c83b62013-01-24 05:28:20199// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
200// used.
ttuttle859dc7a2015-04-23 19:42:29201void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25202 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20203 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19204 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20205
206 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
207 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
208
ttuttle859dc7a2015-04-23 19:42:29209 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
210 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20211 EXPECT_LE(load_timing_info.connect_timing.connect_end,
212 load_timing_info.send_start);
213
214 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20215
[email protected]3b23a222013-05-15 21:33:25216 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20217 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
218 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25219 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20220}
221
222// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
223// used.
ttuttle859dc7a2015-04-23 19:42:29224void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20225 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19226 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20227
ttuttle859dc7a2015-04-23 19:42:29228 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20229
230 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
231 EXPECT_LE(load_timing_info.proxy_resolve_start,
232 load_timing_info.proxy_resolve_end);
233 EXPECT_LE(load_timing_info.proxy_resolve_end,
234 load_timing_info.send_start);
235 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20236
[email protected]3b23a222013-05-15 21:33:25237 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20238 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
239 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25240 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20241}
242
243// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
244// used.
ttuttle859dc7a2015-04-23 19:42:29245void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20246 int connect_timing_flags) {
247 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19248 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20249
250 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
251 EXPECT_LE(load_timing_info.proxy_resolve_start,
252 load_timing_info.proxy_resolve_end);
253 EXPECT_LE(load_timing_info.proxy_resolve_end,
254 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29255 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
256 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20257 EXPECT_LE(load_timing_info.connect_timing.connect_end,
258 load_timing_info.send_start);
259
260 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20261
[email protected]3b23a222013-05-15 21:33:25262 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20263 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
264 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25265 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25266}
267
danakj1fd259a02016-04-16 03:17:09268std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42269 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34270 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14271}
272
xunjieli96f2a402017-06-05 17:24:27273class FailingProxyResolverFactory : public ProxyResolverFactory {
274 public:
275 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
276
277 // ProxyResolverFactory override.
Lily Houghton99597862018-03-07 16:40:42278 int CreateProxyResolver(const scoped_refptr<PacFileData>& script_data,
279 std::unique_ptr<ProxyResolver>* result,
Bence Békycc5b88a2018-05-25 20:24:17280 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:42281 std::unique_ptr<Request>* request) override {
xunjieli96f2a402017-06-05 17:24:27282 return ERR_PAC_SCRIPT_FAILED;
283 }
284};
285
David Benjamin5cb91132018-04-06 05:54:49286class TestSSLConfigService : public SSLConfigService {
287 public:
288 explicit TestSSLConfigService(const SSLConfig& config) : config_(config) {}
Ryan Sleevib8449e02018-07-15 04:31:07289 ~TestSSLConfigService() override = default;
David Benjamin5cb91132018-04-06 05:54:49290
291 void GetSSLConfig(SSLConfig* config) override { *config = config_; }
292
Nick Harper89bc7212018-07-31 19:07:57293 bool CanShareConnectionWithClientCerts(
294 const std::string& hostname) const override {
295 return false;
296 }
297
David Benjamin5cb91132018-04-06 05:54:49298 private:
David Benjamin5cb91132018-04-06 05:54:49299 SSLConfig config_;
300};
301
[email protected]448d4ca52012-03-04 04:12:23302} // namespace
303
Bence Béky98447b12018-05-08 03:14:01304class HttpNetworkTransactionTest : public PlatformTest,
305 public WithScopedTaskEnvironment {
[email protected]483fa202013-05-14 01:07:03306 public:
bncd16676a2016-07-20 16:23:01307 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03308 // Important to restore the per-pool limit first, since the pool limit must
309 // always be greater than group limit, and the tests reduce both limits.
310 ClientSocketPoolManager::set_max_sockets_per_pool(
311 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
312 ClientSocketPoolManager::set_max_sockets_per_group(
313 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
314 }
315
[email protected]e3ceb682011-06-28 23:55:46316 protected:
[email protected]23e482282013-06-14 16:08:02317 HttpNetworkTransactionTest()
bnc032658ba2016-09-26 18:17:15318 : ssl_(ASYNC, OK),
319 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03320 HttpNetworkSession::NORMAL_SOCKET_POOL)),
321 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
322 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28323 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03324 }
[email protected]bb88e1d32013-05-03 23:11:07325
[email protected]e3ceb682011-06-28 23:55:46326 struct SimpleGetHelperResult {
327 int rv;
328 std::string status_line;
329 std::string response_data;
sclittlefb249892015-09-10 21:33:22330 int64_t total_received_bytes;
331 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25332 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47333 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59334 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46335 };
336
dcheng67be2b1f2014-10-27 21:47:29337 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50338 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55339 base::RunLoop().RunUntilIdle();
[email protected]2ff8b312010-04-26 22:20:54340 }
341
dcheng67be2b1f2014-10-27 21:47:29342 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50343 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55344 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09345 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55346 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09347 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50348 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55349 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09350 }
351
[email protected]202965992011-12-07 23:04:51352 // Either |write_failure| specifies a write failure or |read_failure|
353 // specifies a read failure when using a reused socket. In either case, the
354 // failure should cause the network transaction to resend the request, and the
355 // other argument should be NULL.
356 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
357 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52358
[email protected]a34f61ee2014-03-18 20:59:49359 // Either |write_failure| specifies a write failure or |read_failure|
360 // specifies a read failure when using a reused socket. In either case, the
361 // failure should cause the network transaction to resend the request, and the
362 // other argument should be NULL.
363 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10364 const MockRead* read_failure,
365 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49366
Ryan Sleevib8d7ea02018-05-07 20:01:01367 SimpleGetHelperResult SimpleGetHelperForData(
368 base::span<StaticSocketDataProvider*> providers) {
[email protected]ff007e162009-05-23 09:13:15369 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52370
[email protected]ff007e162009-05-23 09:13:15371 HttpRequestInfo request;
372 request.method = "GET";
bncce36dca22015-04-21 22:11:23373 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:10374 request.traffic_annotation =
375 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:52376
vishal.b62985ca92015-04-17 08:45:51377 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07378 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09379 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16380 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27381
Ryan Sleevib8d7ea02018-05-07 20:01:01382 for (auto* provider : providers) {
383 session_deps_.socket_factory->AddSocketDataProvider(provider);
[email protected]5a60c8b2011-10-19 20:14:29384 }
initial.commit586acc5fe2008-07-26 22:42:52385
[email protected]49639fa2011-12-20 23:22:41386 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52387
eroman24bc6a12015-05-06 19:55:48388 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16389 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01390 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52391
[email protected]ff007e162009-05-23 09:13:15392 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16393 out.total_received_bytes = trans.GetTotalReceivedBytes();
394 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25395
396 // Even in the failure cases that use this function, connections are always
397 // successfully established before the error.
bnc691fda62016-08-12 00:43:16398 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25399 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
400
[email protected]ff007e162009-05-23 09:13:15401 if (out.rv != OK)
402 return out;
403
bnc691fda62016-08-12 00:43:16404 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50405 // Can't use ASSERT_* inside helper functions like this, so
406 // return an error.
wezca1070932016-05-26 20:30:52407 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50408 out.rv = ERR_UNEXPECTED;
409 return out;
410 }
[email protected]ff007e162009-05-23 09:13:15411 out.status_line = response->headers->GetStatusLine();
412
[email protected]80a09a82012-11-16 17:40:06413 EXPECT_EQ("127.0.0.1", response->socket_address.host());
414 EXPECT_EQ(80, response->socket_address.port());
[email protected]6d81b482011-02-22 19:47:19415
ttuttled9dbc652015-09-29 20:00:59416 bool got_endpoint =
bnc691fda62016-08-12 00:43:16417 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59418 EXPECT_EQ(got_endpoint,
419 out.remote_endpoint_after_start.address().size() > 0);
420
bnc691fda62016-08-12 00:43:16421 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01422 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40423
mmenke43758e62015-05-04 21:09:46424 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40425 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39426 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00427 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
428 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39429 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00430 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
431 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15432
[email protected]f3da152d2012-06-02 01:00:57433 std::string line;
434 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
435 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
436
[email protected]79e1fd62013-06-20 06:50:04437 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16438 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04439 std::string value;
440 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23441 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04442 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
443 EXPECT_EQ("keep-alive", value);
444
445 std::string response_headers;
446 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23447 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04448 response_headers);
[email protected]3deb9a52010-11-11 00:24:40449
bnc691fda62016-08-12 00:43:16450 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22451 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16452 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22453
bnc691fda62016-08-12 00:43:16454 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47455 return out;
[email protected]ff007e162009-05-23 09:13:15456 }
initial.commit586acc5fe2008-07-26 22:42:52457
Ryan Sleevib8d7ea02018-05-07 20:01:01458 SimpleGetHelperResult SimpleGetHelper(base::span<const MockRead> data_reads) {
sclittlefb249892015-09-10 21:33:22459 MockWrite data_writes[] = {
460 MockWrite("GET / HTTP/1.1\r\n"
461 "Host: www.example.org\r\n"
462 "Connection: keep-alive\r\n\r\n"),
463 };
[email protected]5a60c8b2011-10-19 20:14:29464
Ryan Sleevib8d7ea02018-05-07 20:01:01465 StaticSocketDataProvider reads(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:22466 StaticSocketDataProvider* data[] = {&reads};
Ryan Sleevib8d7ea02018-05-07 20:01:01467 SimpleGetHelperResult out = SimpleGetHelperForData(data);
sclittlefb249892015-09-10 21:33:22468
Ryan Sleevib8d7ea02018-05-07 20:01:01469 EXPECT_EQ(CountWriteBytes(data_writes), out.total_sent_bytes);
sclittlefb249892015-09-10 21:33:22470 return out;
[email protected]b8015c42013-12-24 15:18:19471 }
472
bnc032658ba2016-09-26 18:17:15473 void AddSSLSocketData() {
474 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49475 ssl_.ssl_info.cert =
476 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
477 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15478 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
479 }
480
[email protected]ff007e162009-05-23 09:13:15481 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
482 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52483
[email protected]ff007e162009-05-23 09:13:15484 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07485
[email protected]bb88e1d32013-05-03 23:11:07486 void CheckErrorIsPassedBack(int error, IoMode mode);
487
Douglas Creager134b52e2018-11-09 18:00:14488 // These clocks are defined here, even though they're only used in the
489 // Reporting tests below, since they need to be destroyed after
490 // |session_deps_|.
491 base::SimpleTestClock clock_;
492 base::SimpleTestTickClock tick_clock_;
493
[email protected]4bd46222013-05-14 19:32:23494 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07495 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15496 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03497
498 // Original socket limits. Some tests set these. Safest to always restore
499 // them once each test has been run.
500 int old_max_group_sockets_;
501 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15502};
[email protected]231d5a32008-09-13 00:45:27503
[email protected]448d4ca52012-03-04 04:12:23504namespace {
505
ryansturm49a8cb12016-06-15 16:51:09506class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27507 public:
ryansturm49a8cb12016-06-15 16:51:09508 BeforeHeadersSentHandler()
509 : observed_before_headers_sent_with_proxy_(false),
510 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27511
ryansturm49a8cb12016-06-15 16:51:09512 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
513 HttpRequestHeaders* request_headers) {
514 observed_before_headers_sent_ = true;
515 if (!proxy_info.is_http() && !proxy_info.is_https() &&
516 !proxy_info.is_quic()) {
517 return;
518 }
519 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27520 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
521 }
522
ryansturm49a8cb12016-06-15 16:51:09523 bool observed_before_headers_sent_with_proxy() const {
524 return observed_before_headers_sent_with_proxy_;
525 }
526
527 bool observed_before_headers_sent() const {
528 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27529 }
530
531 std::string observed_proxy_server_uri() const {
532 return observed_proxy_server_uri_;
533 }
534
535 private:
ryansturm49a8cb12016-06-15 16:51:09536 bool observed_before_headers_sent_with_proxy_;
537 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27538 std::string observed_proxy_server_uri_;
539
ryansturm49a8cb12016-06-15 16:51:09540 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27541};
542
[email protected]15a5ccf82008-10-23 19:57:43543// Fill |str| with a long header list that consumes >= |size| bytes.
544void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51545 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19546 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
547 const int sizeof_row = strlen(row);
548 const int num_rows = static_cast<int>(
549 ceil(static_cast<float>(size) / sizeof_row));
550 const int sizeof_data = num_rows * sizeof_row;
551 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43552 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51553
[email protected]4ddaf2502008-10-23 18:26:19554 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43555 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19556}
557
thakis84dff942015-07-28 20:47:38558#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09559uint64_t MockGetMSTime() {
560 // Tue, 23 May 2017 20:13:07 +0000
561 return 131400439870000000;
562}
563
[email protected]385a4672009-03-11 22:21:29564// Alternative functions that eliminate randomness and dependency on the local
565// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37566void MockGenerateRandom(uint8_t* output, size_t n) {
567 // This is set to 0xaa because the client challenge for testing in
568 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
569 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29570}
571
[email protected]fe2bc6a2009-03-23 16:52:20572std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37573 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29574}
thakis84dff942015-07-28 20:47:38575#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29576
[email protected]e60e47a2010-07-14 03:37:18577template<typename ParentPool>
578class CaptureGroupNameSocketPool : public ParentPool {
[email protected]04e5be32009-06-26 20:00:31579 public:
[email protected]9e1bdd32011-02-03 21:48:34580 CaptureGroupNameSocketPool(HostResolver* host_resolver,
581 CertVerifier* cert_verifier);
[email protected]e60e47a2010-07-14 03:37:18582
[email protected]d80a4322009-08-14 07:07:49583 const std::string last_group_name_received() const {
584 return last_group_name_;
585 }
586
Tarun Bansal162eabe52018-01-20 01:16:39587 bool socket_requested() const { return socket_requested_; }
588
dmichaeld6e570d2014-12-18 22:30:57589 int RequestSocket(const std::string& group_name,
590 const void* socket_params,
591 RequestPriority priority,
Paul Jensen8d6f87ec2018-01-13 00:46:54592 const SocketTag& socket_tag,
mmenked3641e12016-01-28 16:06:15593 ClientSocketPool::RespectLimits respect_limits,
dmichaeld6e570d2014-12-18 22:30:57594 ClientSocketHandle* handle,
Bence Béky5a8662b2018-07-03 13:04:03595 CompletionOnceCallback callback,
tfarina42834112016-09-22 13:38:20596 const NetLogWithSource& net_log) override {
[email protected]04e5be32009-06-26 20:00:31597 last_group_name_ = group_name;
Tarun Bansal162eabe52018-01-20 01:16:39598 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31599 return ERR_IO_PENDING;
600 }
dmichaeld6e570d2014-12-18 22:30:57601 void CancelRequest(const std::string& group_name,
602 ClientSocketHandle* handle) override {}
603 void ReleaseSocket(const std::string& group_name,
danakj1fd259a02016-04-16 03:17:09604 std::unique_ptr<StreamSocket> socket,
dmichaeld6e570d2014-12-18 22:30:57605 int id) override {}
606 void CloseIdleSockets() override {}
xunjieli92feb332017-03-03 17:19:23607 void CloseIdleSocketsInGroup(const std::string& group_name) override {}
dmichaeld6e570d2014-12-18 22:30:57608 int IdleSocketCount() const override { return 0; }
609 int IdleSocketCountInGroup(const std::string& group_name) const override {
[email protected]04e5be32009-06-26 20:00:31610 return 0;
611 }
dmichaeld6e570d2014-12-18 22:30:57612 LoadState GetLoadState(const std::string& group_name,
613 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31614 return LOAD_STATE_IDLE;
615 }
dmichaeld6e570d2014-12-18 22:30:57616 base::TimeDelta ConnectionTimeout() const override {
[email protected]a796bcec2010-03-22 17:17:26617 return base::TimeDelta();
618 }
[email protected]d80a4322009-08-14 07:07:49619
620 private:
[email protected]04e5be32009-06-26 20:00:31621 std::string last_group_name_;
Tarun Bansal162eabe52018-01-20 01:16:39622 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31623};
624
[email protected]ab739042011-04-07 15:22:28625typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
626CaptureGroupNameTransportSocketPool;
[email protected]e772db3f2010-07-12 18:11:13627typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
628CaptureGroupNameHttpProxySocketPool;
[email protected]2d731a32010-04-29 01:04:06629typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
[email protected]2227c692010-05-04 15:36:11630CaptureGroupNameSOCKSSocketPool;
[email protected]e60e47a2010-07-14 03:37:18631typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
632CaptureGroupNameSSLSocketPool;
633
rkaplowd90695c2015-03-25 22:12:41634template <typename ParentPool>
[email protected]e60e47a2010-07-14 03:37:18635CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
[email protected]9e1bdd32011-02-03 21:48:34636 HostResolver* host_resolver,
637 CertVerifier* /* cert_verifier */)
tbansal7b403bcc2016-04-13 22:33:21638 : ParentPool(0, 0, host_resolver, NULL, NULL, NULL) {}
[email protected]e60e47a2010-07-14 03:37:18639
hashimoto0d3e4fb2015-01-09 05:02:50640template <>
[email protected]2df19bb2010-08-25 20:13:46641CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21642 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34643 CertVerifier* /* cert_verifier */)
tbansal16196a1e2017-06-09 01:50:09644 : HttpProxyClientSocketPool(0, 0, NULL, NULL, NULL, NULL) {}
[email protected]2df19bb2010-08-25 20:13:46645
[email protected]007b3f82013-04-09 08:46:45646template <>
[email protected]e60e47a2010-07-14 03:37:18647CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
hashimotodae13b02015-01-15 04:28:21648 HostResolver* /* host_resolver */,
[email protected]9e1bdd32011-02-03 21:48:34649 CertVerifier* cert_verifier)
[email protected]007b3f82013-04-09 08:46:45650 : SSLClientSocketPool(0,
651 0,
[email protected]007b3f82013-04-09 08:46:45652 cert_verifier,
653 NULL,
654 NULL,
[email protected]284303b62013-11-28 15:11:54655 NULL,
eranm6571b2b2014-12-03 15:53:23656 NULL,
[email protected]007b3f82013-04-09 08:46:45657 std::string(),
658 NULL,
659 NULL,
660 NULL,
661 NULL,
662 NULL,
[email protected]8e458552014-08-05 00:02:15663 NULL) {
664}
[email protected]2227c692010-05-04 15:36:11665
[email protected]231d5a32008-09-13 00:45:27666//-----------------------------------------------------------------------------
667
[email protected]79cb5c12011-09-12 13:12:04668// Helper functions for validating that AuthChallengeInfo's are correctly
669// configured for common cases.
670bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
671 if (!auth_challenge)
672 return false;
673 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43674 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04675 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19676 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04677 return true;
678}
679
680bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
681 if (!auth_challenge)
682 return false;
683 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43684 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
685 EXPECT_EQ("MyRealm1", auth_challenge->realm);
686 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
687 return true;
688}
689
690bool CheckBasicSecureProxyAuth(const AuthChallengeInfo* auth_challenge) {
691 if (!auth_challenge)
692 return false;
693 EXPECT_TRUE(auth_challenge->is_proxy);
694 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04695 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19696 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04697 return true;
698}
699
700bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
701 if (!auth_challenge)
702 return false;
703 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43704 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04705 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19706 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04707 return true;
708}
709
thakis84dff942015-07-28 20:47:38710#if defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04711bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
712 if (!auth_challenge)
713 return false;
714 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55715 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04716 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19717 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04718 return true;
719}
David Benjamin5cb91132018-04-06 05:54:49720
721bool CheckNTLMProxyAuth(const AuthChallengeInfo* auth_challenge) {
722 if (!auth_challenge)
723 return false;
724 EXPECT_TRUE(auth_challenge->is_proxy);
725 EXPECT_EQ("http://server", auth_challenge->challenger.Serialize());
726 EXPECT_EQ(std::string(), auth_challenge->realm);
727 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
728 return true;
729}
thakis84dff942015-07-28 20:47:38730#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04731
[email protected]448d4ca52012-03-04 04:12:23732} // namespace
733
bncd16676a2016-07-20 16:23:01734TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09735 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16736 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27737}
738
bncd16676a2016-07-20 16:23:01739TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27740 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35741 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
742 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06743 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27744 };
Ryan Sleevib8d7ea02018-05-07 20:01:01745 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01746 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27747 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
748 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01749 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22750 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47751 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59752
753 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27754}
755
756// Response with no status line.
bncd16676a2016-07-20 16:23:01757TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27758 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35759 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06760 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27761 };
Ryan Sleevib8d7ea02018-05-07 20:01:01762 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41763 EXPECT_THAT(out.rv, IsOk());
764 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
765 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01766 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41767 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27768}
769
mmenkea7da6da2016-09-01 21:56:52770// Response with no status line, and a weird port. Should fail by default.
771TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
772 MockRead data_reads[] = {
773 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
774 };
775
Ryan Sleevib8d7ea02018-05-07 20:01:01776 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52777 session_deps_.socket_factory->AddSocketDataProvider(&data);
778
779 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
780
krasinc06a72a2016-12-21 03:42:46781 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58782 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19783 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52784
mmenkea7da6da2016-09-01 21:56:52785 request.method = "GET";
786 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10787 request.traffic_annotation =
788 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
789
mmenkea7da6da2016-09-01 21:56:52790 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20791 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52792 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
793}
794
Shivani Sharmafdcaefd2017-11-02 00:12:26795// Tests that request info can be destroyed after the headers phase is complete.
796TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
797 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
798 auto trans =
799 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
800
801 MockRead data_reads[] = {
802 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
803 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
804 };
Ryan Sleevib8d7ea02018-05-07 20:01:01805 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Shivani Sharmafdcaefd2017-11-02 00:12:26806 session_deps_.socket_factory->AddSocketDataProvider(&data);
807
808 TestCompletionCallback callback;
809
810 {
811 auto request = std::make_unique<HttpRequestInfo>();
812 request->method = "GET";
813 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:10814 request->traffic_annotation =
815 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26816
817 int rv =
818 trans->Start(request.get(), callback.callback(), NetLogWithSource());
819
820 EXPECT_THAT(callback.GetResult(rv), IsOk());
821 } // Let request info be destroyed.
822
823 trans.reset();
824}
825
mmenkea7da6da2016-09-01 21:56:52826// Response with no status line, and a weird port. Option to allow weird ports
827// enabled.
828TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
829 MockRead data_reads[] = {
830 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
831 };
832
Ryan Sleevib8d7ea02018-05-07 20:01:01833 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52834 session_deps_.socket_factory->AddSocketDataProvider(&data);
835 session_deps_.http_09_on_non_default_ports_enabled = true;
836 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
837
krasinc06a72a2016-12-21 03:42:46838 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58839 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19840 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52841
mmenkea7da6da2016-09-01 21:56:52842 request.method = "GET";
843 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e2018-02-07 07:41:10844 request.traffic_annotation =
845 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
846
mmenkea7da6da2016-09-01 21:56:52847 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20848 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52849 EXPECT_THAT(callback.GetResult(rv), IsOk());
850
851 const HttpResponseInfo* info = trans->GetResponseInfo();
852 ASSERT_TRUE(info->headers);
853 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
854
855 // Don't bother to read the body - that's verified elsewhere, important thing
856 // is that the option to allow HTTP/0.9 on non-default ports is respected.
857}
858
[email protected]231d5a32008-09-13 00:45:27859// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01860TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27861 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35862 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06863 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27864 };
Ryan Sleevib8d7ea02018-05-07 20:01:01865 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01866 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27867 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
868 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01869 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22870 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27871}
872
873// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01874TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27875 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35876 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06877 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27878 };
Ryan Sleevib8d7ea02018-05-07 20:01:01879 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01880 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27881 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
882 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01883 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22884 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27885}
886
887// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01888TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27889 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35890 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06891 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27892 };
Ryan Sleevib8d7ea02018-05-07 20:01:01893 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41894 EXPECT_THAT(out.rv, IsOk());
895 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
896 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01897 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41898 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27899}
900
901// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01902TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27903 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35904 MockRead("\n"),
905 MockRead("\n"),
906 MockRead("Q"),
907 MockRead("J"),
908 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06909 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27910 };
Ryan Sleevib8d7ea02018-05-07 20:01:01911 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01912 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27913 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
914 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01915 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22916 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27917}
918
919// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01920TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27921 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35922 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06923 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27924 };
Ryan Sleevib8d7ea02018-05-07 20:01:01925 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41926 EXPECT_THAT(out.rv, IsOk());
927 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
928 EXPECT_EQ("HTT", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01929 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41930 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52931}
932
[email protected]f9d44aa2008-09-23 23:57:17933// Simulate a 204 response, lacking a Content-Length header, sent over a
934// persistent connection. The response should still terminate since a 204
935// cannot have a response body.
bncd16676a2016-07-20 16:23:01936TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19937 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:17938 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35939 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:19940 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:06941 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:17942 };
Ryan Sleevib8d7ea02018-05-07 20:01:01943 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01944 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:17945 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
946 EXPECT_EQ("", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01947 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22948 int64_t response_size = reads_size - strlen(junk);
949 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:17950}
951
[email protected]0877e3d2009-10-17 22:29:57952// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:01953TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:19954 std::string final_chunk = "0\r\n\r\n";
955 std::string extra_data = "HTTP/1.1 200 OK\r\n";
956 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:57957 MockRead data_reads[] = {
958 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
959 MockRead("5\r\nHello\r\n"),
960 MockRead("1\r\n"),
961 MockRead(" \r\n"),
962 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:19963 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:06964 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:57965 };
Ryan Sleevib8d7ea02018-05-07 20:01:01966 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01967 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:57968 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
969 EXPECT_EQ("Hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01970 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22971 int64_t response_size = reads_size - extra_data.size();
972 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:57973}
974
[email protected]9fe44f52010-09-23 18:36:00975// Next tests deal with http://crbug.com/56344.
976
bncd16676a2016-07-20 16:23:01977TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:00978 MultipleContentLengthHeadersNoTransferEncoding) {
979 MockRead data_reads[] = {
980 MockRead("HTTP/1.1 200 OK\r\n"),
981 MockRead("Content-Length: 10\r\n"),
982 MockRead("Content-Length: 5\r\n\r\n"),
983 };
Ryan Sleevib8d7ea02018-05-07 20:01:01984 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01985 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:00986}
987
bncd16676a2016-07-20 16:23:01988TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:04989 DuplicateContentLengthHeadersNoTransferEncoding) {
990 MockRead data_reads[] = {
991 MockRead("HTTP/1.1 200 OK\r\n"),
992 MockRead("Content-Length: 5\r\n"),
993 MockRead("Content-Length: 5\r\n\r\n"),
994 MockRead("Hello"),
995 };
Ryan Sleevib8d7ea02018-05-07 20:01:01996 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01997 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:04998 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
999 EXPECT_EQ("Hello", out.response_data);
1000}
1001
bncd16676a2016-07-20 16:23:011002TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041003 ComplexContentLengthHeadersNoTransferEncoding) {
1004 // More than 2 dupes.
1005 {
1006 MockRead data_reads[] = {
1007 MockRead("HTTP/1.1 200 OK\r\n"),
1008 MockRead("Content-Length: 5\r\n"),
1009 MockRead("Content-Length: 5\r\n"),
1010 MockRead("Content-Length: 5\r\n\r\n"),
1011 MockRead("Hello"),
1012 };
Ryan Sleevib8d7ea02018-05-07 20:01:011013 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011014 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041015 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1016 EXPECT_EQ("Hello", out.response_data);
1017 }
1018 // HTTP/1.0
1019 {
1020 MockRead data_reads[] = {
1021 MockRead("HTTP/1.0 200 OK\r\n"),
1022 MockRead("Content-Length: 5\r\n"),
1023 MockRead("Content-Length: 5\r\n"),
1024 MockRead("Content-Length: 5\r\n\r\n"),
1025 MockRead("Hello"),
1026 };
Ryan Sleevib8d7ea02018-05-07 20:01:011027 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011028 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041029 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1030 EXPECT_EQ("Hello", out.response_data);
1031 }
1032 // 2 dupes and one mismatched.
1033 {
1034 MockRead data_reads[] = {
1035 MockRead("HTTP/1.1 200 OK\r\n"),
1036 MockRead("Content-Length: 10\r\n"),
1037 MockRead("Content-Length: 10\r\n"),
1038 MockRead("Content-Length: 5\r\n\r\n"),
1039 };
Ryan Sleevib8d7ea02018-05-07 20:01:011040 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011041 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041042 }
1043}
1044
bncd16676a2016-07-20 16:23:011045TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001046 MultipleContentLengthHeadersTransferEncoding) {
1047 MockRead data_reads[] = {
1048 MockRead("HTTP/1.1 200 OK\r\n"),
1049 MockRead("Content-Length: 666\r\n"),
1050 MockRead("Content-Length: 1337\r\n"),
1051 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1052 MockRead("5\r\nHello\r\n"),
1053 MockRead("1\r\n"),
1054 MockRead(" \r\n"),
1055 MockRead("5\r\nworld\r\n"),
1056 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061057 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001058 };
Ryan Sleevib8d7ea02018-05-07 20:01:011059 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011060 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001061 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1062 EXPECT_EQ("Hello world", out.response_data);
1063}
1064
[email protected]1628fe92011-10-04 23:04:551065// Next tests deal with http://crbug.com/98895.
1066
1067// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011068TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551069 MockRead data_reads[] = {
1070 MockRead("HTTP/1.1 200 OK\r\n"),
1071 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1072 MockRead("Content-Length: 5\r\n\r\n"),
1073 MockRead("Hello"),
1074 };
Ryan Sleevib8d7ea02018-05-07 20:01:011075 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011076 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551077 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1078 EXPECT_EQ("Hello", out.response_data);
1079}
1080
[email protected]54a9c6e52012-03-21 20:10:591081// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011082TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551083 MockRead data_reads[] = {
1084 MockRead("HTTP/1.1 200 OK\r\n"),
1085 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1086 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1087 MockRead("Content-Length: 5\r\n\r\n"),
1088 MockRead("Hello"),
1089 };
Ryan Sleevib8d7ea02018-05-07 20:01:011090 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011091 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591092 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1093 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551094}
1095
1096// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011097TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551098 MockRead data_reads[] = {
1099 MockRead("HTTP/1.1 200 OK\r\n"),
1100 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1101 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1102 MockRead("Content-Length: 5\r\n\r\n"),
1103 MockRead("Hello"),
1104 };
Ryan Sleevib8d7ea02018-05-07 20:01:011105 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011106 EXPECT_THAT(out.rv,
1107 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551108}
1109
[email protected]54a9c6e52012-03-21 20:10:591110// Checks that two identical Location headers result in no error.
1111// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011112TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551113 MockRead data_reads[] = {
1114 MockRead("HTTP/1.1 302 Redirect\r\n"),
1115 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591116 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551117 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061118 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551119 };
1120
1121 HttpRequestInfo request;
1122 request.method = "GET";
1123 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101124 request.traffic_annotation =
1125 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551126
danakj1fd259a02016-04-16 03:17:091127 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161128 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551129
Ryan Sleevib8d7ea02018-05-07 20:01:011130 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071131 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551132
[email protected]49639fa2011-12-20 23:22:411133 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551134
tfarina42834112016-09-22 13:38:201135 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011136 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551137
robpercival214763f2016-07-01 23:27:011138 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551139
bnc691fda62016-08-12 00:43:161140 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521141 ASSERT_TRUE(response);
1142 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551143 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1144 std::string url;
1145 EXPECT_TRUE(response->headers->IsRedirect(&url));
1146 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471147 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551148}
1149
[email protected]1628fe92011-10-04 23:04:551150// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011151TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551152 MockRead data_reads[] = {
1153 MockRead("HTTP/1.1 302 Redirect\r\n"),
1154 MockRead("Location: http://good.com/\r\n"),
1155 MockRead("Location: http://evil.com/\r\n"),
1156 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061157 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551158 };
Ryan Sleevib8d7ea02018-05-07 20:01:011159 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011160 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551161}
1162
[email protected]ef0faf2e72009-03-05 23:27:231163// Do a request using the HEAD method. Verify that we don't try to read the
1164// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011165TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421166 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231167 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231168 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101169 request.traffic_annotation =
1170 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231171
danakj1fd259a02016-04-16 03:17:091172 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161173 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091174 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161175 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091176 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1177 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271178
[email protected]ef0faf2e72009-03-05 23:27:231179 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131180 MockWrite("HEAD / HTTP/1.1\r\n"
1181 "Host: www.example.org\r\n"
1182 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231183 };
1184 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231185 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1186 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231187
mmenked39192ee2015-12-09 00:57:231188 // No response body because the test stops reading here.
1189 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231190 };
1191
Ryan Sleevib8d7ea02018-05-07 20:01:011192 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:071193 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231194
[email protected]49639fa2011-12-20 23:22:411195 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231196
tfarina42834112016-09-22 13:38:201197 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011198 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231199
1200 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011201 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231202
bnc691fda62016-08-12 00:43:161203 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521204 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231205
1206 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521207 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231208 EXPECT_EQ(1234, response->headers->GetContentLength());
1209 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471210 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091211 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1212 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231213
1214 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101215 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231216 bool has_server_header = response->headers->EnumerateHeader(
1217 &iter, "Server", &server_header);
1218 EXPECT_TRUE(has_server_header);
1219 EXPECT_EQ("Blah", server_header);
1220
1221 // Reading should give EOF right away, since there is no message body
1222 // (despite non-zero content-length).
1223 std::string response_data;
bnc691fda62016-08-12 00:43:161224 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011225 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231226 EXPECT_EQ("", response_data);
1227}
1228
bncd16676a2016-07-20 16:23:011229TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091230 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521231
1232 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351233 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1234 MockRead("hello"),
1235 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1236 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061237 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521238 };
Ryan Sleevib8d7ea02018-05-07 20:01:011239 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071240 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521241
[email protected]0b0bf032010-09-21 18:08:501242 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521243 "hello", "world"
1244 };
1245
1246 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421247 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521248 request.method = "GET";
bncce36dca22015-04-21 22:11:231249 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101250 request.traffic_annotation =
1251 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521252
bnc691fda62016-08-12 00:43:161253 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271254
[email protected]49639fa2011-12-20 23:22:411255 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521256
tfarina42834112016-09-22 13:38:201257 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011258 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521259
1260 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011261 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521262
bnc691fda62016-08-12 00:43:161263 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521264 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521265
wezca1070932016-05-26 20:30:521266 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251267 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471268 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521269
1270 std::string response_data;
bnc691fda62016-08-12 00:43:161271 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011272 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251273 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521274 }
1275}
1276
bncd16676a2016-07-20 16:23:011277TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091278 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221279 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191280 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221281 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271282
[email protected]1c773ea12009-04-28 19:58:421283 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521284 request.method = "POST";
1285 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271286 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:101287 request.traffic_annotation =
1288 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521289
shivanishab9a143952016-09-19 17:23:411290 // Check the upload progress returned before initialization is correct.
1291 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1292 EXPECT_EQ(0u, progress.size());
1293 EXPECT_EQ(0u, progress.position());
1294
danakj1fd259a02016-04-16 03:17:091295 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161296 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271297
initial.commit586acc5fe2008-07-26 22:42:521298 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351299 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1300 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1301 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061302 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521303 };
Ryan Sleevib8d7ea02018-05-07 20:01:011304 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071305 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521306
[email protected]49639fa2011-12-20 23:22:411307 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521308
tfarina42834112016-09-22 13:38:201309 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011310 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521311
1312 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011313 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521314
bnc691fda62016-08-12 00:43:161315 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521316 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521317
wezca1070932016-05-26 20:30:521318 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251319 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521320
1321 std::string response_data;
bnc691fda62016-08-12 00:43:161322 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011323 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251324 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521325}
1326
[email protected]3a2d3662009-03-27 03:49:141327// This test is almost the same as Ignores100 above, but the response contains
1328// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571329// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011330TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421331 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141332 request.method = "GET";
1333 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101334 request.traffic_annotation =
1335 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141336
danakj1fd259a02016-04-16 03:17:091337 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161338 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271339
[email protected]3a2d3662009-03-27 03:49:141340 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571341 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1342 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141343 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061344 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141345 };
Ryan Sleevib8d7ea02018-05-07 20:01:011346 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071347 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141348
[email protected]49639fa2011-12-20 23:22:411349 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141350
tfarina42834112016-09-22 13:38:201351 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011352 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141353
1354 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011355 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141356
bnc691fda62016-08-12 00:43:161357 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521358 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141359
wezca1070932016-05-26 20:30:521360 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141361 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1362
1363 std::string response_data;
bnc691fda62016-08-12 00:43:161364 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011365 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141366 EXPECT_EQ("hello world", response_data);
1367}
1368
bncd16676a2016-07-20 16:23:011369TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081370 HttpRequestInfo request;
1371 request.method = "POST";
1372 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101373 request.traffic_annotation =
1374 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081375
danakj1fd259a02016-04-16 03:17:091376 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161377 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081378
1379 MockRead data_reads[] = {
1380 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1381 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381382 };
Ryan Sleevib8d7ea02018-05-07 20:01:011383 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
zmo9528c9f42015-08-04 22:12:081384 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381385
zmo9528c9f42015-08-04 22:12:081386 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381387
tfarina42834112016-09-22 13:38:201388 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011389 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381390
zmo9528c9f42015-08-04 22:12:081391 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011392 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381393
zmo9528c9f42015-08-04 22:12:081394 std::string response_data;
bnc691fda62016-08-12 00:43:161395 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011396 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081397 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381398}
1399
bncd16676a2016-07-20 16:23:011400TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381401 HttpRequestInfo request;
1402 request.method = "POST";
1403 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101404 request.traffic_annotation =
1405 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381406
danakj1fd259a02016-04-16 03:17:091407 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161408 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271409
[email protected]ee9410e72010-01-07 01:42:381410 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061411 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381412 };
Ryan Sleevib8d7ea02018-05-07 20:01:011413 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071414 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381415
[email protected]49639fa2011-12-20 23:22:411416 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381417
tfarina42834112016-09-22 13:38:201418 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011419 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381420
1421 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011422 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381423}
1424
[email protected]23e482282013-06-14 16:08:021425void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511426 const MockWrite* write_failure,
1427 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421428 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521429 request.method = "GET";
1430 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101431 request.traffic_annotation =
1432 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521433
vishal.b62985ca92015-04-17 08:45:511434 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071435 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091436 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271437
[email protected]202965992011-12-07 23:04:511438 // Written data for successfully sending both requests.
1439 MockWrite data1_writes[] = {
1440 MockWrite("GET / HTTP/1.1\r\n"
1441 "Host: www.foo.com\r\n"
1442 "Connection: keep-alive\r\n\r\n"),
1443 MockWrite("GET / HTTP/1.1\r\n"
1444 "Host: www.foo.com\r\n"
1445 "Connection: keep-alive\r\n\r\n")
1446 };
1447
1448 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521449 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351450 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1451 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061452 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521453 };
[email protected]202965992011-12-07 23:04:511454
1455 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491456 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511457 data1_writes[1] = *write_failure;
1458 } else {
1459 ASSERT_TRUE(read_failure);
1460 data1_reads[2] = *read_failure;
1461 }
1462
Ryan Sleevib8d7ea02018-05-07 20:01:011463 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]bb88e1d32013-05-03 23:11:071464 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521465
1466 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351467 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1468 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061469 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521470 };
Ryan Sleevib8d7ea02018-05-07 20:01:011471 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071472 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521473
thestig9d3bb0c2015-01-24 00:49:511474 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521475 "hello", "world"
1476 };
1477
mikecironef22f9812016-10-04 03:40:191478 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521479 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411480 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521481
bnc691fda62016-08-12 00:43:161482 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521483
tfarina42834112016-09-22 13:38:201484 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011485 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521486
1487 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011488 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521489
[email protected]58e32bb2013-01-21 18:23:251490 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161491 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251492 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1493 if (i == 0) {
1494 first_socket_log_id = load_timing_info.socket_log_id;
1495 } else {
1496 // The second request should be using a new socket.
1497 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1498 }
1499
bnc691fda62016-08-12 00:43:161500 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521501 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521502
wezca1070932016-05-26 20:30:521503 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471504 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251505 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521506
1507 std::string response_data;
bnc691fda62016-08-12 00:43:161508 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011509 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251510 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521511 }
1512}
[email protected]3d2a59b2008-09-26 19:44:251513
[email protected]a34f61ee2014-03-18 20:59:491514void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1515 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101516 const MockRead* read_failure,
1517 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491518 HttpRequestInfo request;
1519 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101520 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101521 request.traffic_annotation =
1522 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491523
vishal.b62985ca92015-04-17 08:45:511524 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491525 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091526 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491527
[email protected]09356c652014-03-25 15:36:101528 SSLSocketDataProvider ssl1(ASYNC, OK);
1529 SSLSocketDataProvider ssl2(ASYNC, OK);
1530 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361531 ssl1.next_proto = kProtoHTTP2;
1532 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101533 }
1534 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1535 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491536
[email protected]09356c652014-03-25 15:36:101537 // SPDY versions of the request and response.
Ryan Hamilton0239aac2018-05-19 00:03:131538 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491539 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131540 spdy::SpdySerializedFrame spdy_response(
bnc42331402016-07-25 13:36:151541 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131542 spdy::SpdySerializedFrame spdy_data(
Bence Békyd74f4382018-02-20 18:26:191543 spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
[email protected]a34f61ee2014-03-18 20:59:491544
[email protected]09356c652014-03-25 15:36:101545 // HTTP/1.1 versions of the request and response.
1546 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1547 "Host: www.foo.com\r\n"
1548 "Connection: keep-alive\r\n\r\n";
1549 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1550 const char kHttpData[] = "hello";
1551
1552 std::vector<MockRead> data1_reads;
1553 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491554 if (write_failure) {
1555 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101556 data1_writes.push_back(*write_failure);
1557 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491558 } else {
1559 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101560 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411561 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101562 } else {
1563 data1_writes.push_back(MockWrite(kHttpRequest));
1564 }
1565 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491566 }
1567
Ryan Sleevib8d7ea02018-05-07 20:01:011568 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]a34f61ee2014-03-18 20:59:491569 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1570
[email protected]09356c652014-03-25 15:36:101571 std::vector<MockRead> data2_reads;
1572 std::vector<MockWrite> data2_writes;
1573
1574 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411575 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101576
bncdf80d44fd2016-07-15 20:27:411577 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1578 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101579 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1580 } else {
1581 data2_writes.push_back(
1582 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1583
1584 data2_reads.push_back(
1585 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1586 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1587 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1588 }
Ryan Sleevib8d7ea02018-05-07 20:01:011589 SequencedSocketData data2(data2_reads, data2_writes);
[email protected]a34f61ee2014-03-18 20:59:491590 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1591
1592 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591593 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491594 // Wait for the preconnect to complete.
1595 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1596 base::RunLoop().RunUntilIdle();
[email protected]09356c652014-03-25 15:36:101597 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491598
1599 // Make the request.
1600 TestCompletionCallback callback;
1601
bnc691fda62016-08-12 00:43:161602 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491603
tfarina42834112016-09-22 13:38:201604 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011605 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491606
1607 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011608 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491609
1610 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161611 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101612 TestLoadTimingNotReused(
1613 load_timing_info,
1614 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491615
bnc691fda62016-08-12 00:43:161616 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521617 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491618
wezca1070932016-05-26 20:30:521619 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021620 if (response->was_fetched_via_spdy) {
1621 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1622 } else {
1623 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1624 }
[email protected]a34f61ee2014-03-18 20:59:491625
1626 std::string response_data;
bnc691fda62016-08-12 00:43:161627 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011628 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101629 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491630}
1631
Biljith Jayan45a41722017-08-16 18:43:141632// Test that we do not retry indefinitely when a server sends an error like
1633// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1634// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1635TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1636 HttpRequestInfo request;
1637 request.method = "GET";
1638 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101639 request.traffic_annotation =
1640 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141641
1642 // Check whether we give up after the third try.
1643
1644 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131645 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141646 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131647 spdy::SpdySerializedFrame spdy_response_go_away(
1648 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011649 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1650 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141651
1652 // Three go away responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011653 StaticSocketDataProvider data1(data_read1, data_write);
1654 StaticSocketDataProvider data2(data_read1, data_write);
1655 StaticSocketDataProvider data3(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141656
1657 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1658 AddSSLSocketData();
1659 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1660 AddSSLSocketData();
1661 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1662 AddSSLSocketData();
1663
1664 TestCompletionCallback callback;
1665 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1666 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1667
1668 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1669 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1670
1671 rv = callback.WaitForResult();
1672 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1673}
1674
1675TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1676 HttpRequestInfo request;
1677 request.method = "GET";
1678 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101679 request.traffic_annotation =
1680 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141681
1682 // Check whether we try atleast thrice before giving up.
1683
1684 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131685 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141686 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131687 spdy::SpdySerializedFrame spdy_response_go_away(
1688 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011689 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1690 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141691
1692 // Construct a non error HTTP2 response.
Ryan Hamilton0239aac2018-05-19 00:03:131693 spdy::SpdySerializedFrame spdy_response_no_error(
Biljith Jayan45a41722017-08-16 18:43:141694 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131695 spdy::SpdySerializedFrame spdy_data(
1696 spdy_util_.ConstructSpdyDataFrame(1, true));
Biljith Jayan45a41722017-08-16 18:43:141697 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1698 CreateMockRead(spdy_data, 2)};
1699
1700 // Two error responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011701 StaticSocketDataProvider data1(data_read1, data_write);
1702 StaticSocketDataProvider data2(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141703 // Followed by a success response.
Ryan Sleevib8d7ea02018-05-07 20:01:011704 SequencedSocketData data3(data_read2, data_write);
Biljith Jayan45a41722017-08-16 18:43:141705
1706 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1707 AddSSLSocketData();
1708 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1709 AddSSLSocketData();
1710 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1711 AddSSLSocketData();
1712
1713 TestCompletionCallback callback;
1714 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1715 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1716
1717 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1718 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1719
1720 rv = callback.WaitForResult();
1721 EXPECT_THAT(rv, IsOk());
1722}
1723
bncd16676a2016-07-20 16:23:011724TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061725 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]202965992011-12-07 23:04:511726 KeepAliveConnectionResendRequestTest(&write_failure, NULL);
1727}
1728
bncd16676a2016-07-20 16:23:011729TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061730 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]202965992011-12-07 23:04:511731 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251732}
1733
bncd16676a2016-07-20 16:23:011734TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061735 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]202965992011-12-07 23:04:511736 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251737}
1738
[email protected]d58ceea82014-06-04 10:55:541739// Make sure that on a 408 response (Request Timeout), the request is retried,
1740// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011741TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541742 MockRead read_failure(SYNCHRONOUS,
1743 "HTTP/1.1 408 Request Timeout\r\n"
1744 "Connection: Keep-Alive\r\n"
1745 "Content-Length: 6\r\n\r\n"
1746 "Pickle");
1747 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1748}
1749
bncd16676a2016-07-20 16:23:011750TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491751 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
[email protected]09356c652014-03-25 15:36:101752 PreconnectErrorResendRequestTest(&write_failure, NULL, false);
[email protected]a34f61ee2014-03-18 20:59:491753}
1754
bncd16676a2016-07-20 16:23:011755TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491756 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
[email protected]09356c652014-03-25 15:36:101757 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491758}
1759
bncd16676a2016-07-20 16:23:011760TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:491761 MockRead read_failure(SYNCHRONOUS, OK); // EOF
[email protected]09356c652014-03-25 15:36:101762 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1763}
1764
bncd16676a2016-07-20 16:23:011765TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101766 MockRead read_failure(ASYNC, OK); // EOF
1767 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1768}
1769
[email protected]d58ceea82014-06-04 10:55:541770// Make sure that on a 408 response (Request Timeout), the request is retried,
1771// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:011772TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:541773 MockRead read_failure(SYNCHRONOUS,
1774 "HTTP/1.1 408 Request Timeout\r\n"
1775 "Connection: Keep-Alive\r\n"
1776 "Content-Length: 6\r\n\r\n"
1777 "Pickle");
1778 KeepAliveConnectionResendRequestTest(NULL, &read_failure);
1779 PreconnectErrorResendRequestTest(NULL, &read_failure, false);
1780}
1781
bncd16676a2016-07-20 16:23:011782TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:101783 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
1784 PreconnectErrorResendRequestTest(&write_failure, NULL, true);
1785}
1786
bncd16676a2016-07-20 16:23:011787TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:101788 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
1789 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1790}
1791
bncd16676a2016-07-20 16:23:011792TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:101793 MockRead read_failure(SYNCHRONOUS, OK); // EOF
1794 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
1795}
1796
bncd16676a2016-07-20 16:23:011797TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:101798 MockRead read_failure(ASYNC, OK); // EOF
1799 PreconnectErrorResendRequestTest(NULL, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:491800}
1801
bncd16676a2016-07-20 16:23:011802TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:421803 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:251804 request.method = "GET";
bncce36dca22015-04-21 22:11:231805 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101806 request.traffic_annotation =
1807 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:251808
danakj1fd259a02016-04-16 03:17:091809 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161810 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271811
[email protected]3d2a59b2008-09-26 19:44:251812 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061813 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:351814 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1815 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061816 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251817 };
Ryan Sleevib8d7ea02018-05-07 20:01:011818 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071819 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:251820
[email protected]49639fa2011-12-20 23:22:411821 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:251822
tfarina42834112016-09-22 13:38:201823 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011824 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:251825
1826 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011827 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:591828
1829 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:161830 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:591831 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:251832}
1833
1834// What do various browsers do when the server closes a non-keepalive
1835// connection without sending any response header or body?
1836//
1837// IE7: error page
1838// Safari 3.1.2 (Windows): error page
1839// Firefox 3.0.1: blank page
1840// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:421841// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
1842// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:011843TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:251844 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061845 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:351846 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
1847 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061848 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:251849 };
Ryan Sleevib8d7ea02018-05-07 20:01:011850 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011851 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:251852}
[email protected]1826a402014-01-08 15:40:481853
[email protected]7a5378b2012-11-04 03:25:171854// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
1855// tests. There was a bug causing HttpNetworkTransaction to hang in the
1856// destructor in such situations.
1857// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:011858TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:171859 HttpRequestInfo request;
1860 request.method = "GET";
bncce36dca22015-04-21 22:11:231861 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101862 request.traffic_annotation =
1863 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:171864
danakj1fd259a02016-04-16 03:17:091865 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581866 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191867 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171868
1869 MockRead data_reads[] = {
1870 MockRead("HTTP/1.0 200 OK\r\n"),
1871 MockRead("Connection: keep-alive\r\n"),
1872 MockRead("Content-Length: 100\r\n\r\n"),
1873 MockRead("hello"),
1874 MockRead(SYNCHRONOUS, 0),
1875 };
Ryan Sleevib8d7ea02018-05-07 20:01:011876 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071877 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171878
1879 TestCompletionCallback callback;
1880
tfarina42834112016-09-22 13:38:201881 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011882 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171883
1884 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011885 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171886
Victor Costan9c7302b2018-08-27 16:39:441887 scoped_refptr<IOBufferWithSize> io_buf =
1888 base::MakeRefCounted<IOBufferWithSize>(100);
[email protected]90499482013-06-01 00:39:501889 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171890 if (rv == ERR_IO_PENDING)
1891 rv = callback.WaitForResult();
1892 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:501893 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:011894 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171895
1896 trans.reset();
fdoray92e35a72016-06-10 15:54:551897 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171898 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1899}
1900
bncd16676a2016-07-20 16:23:011901TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:171902 HttpRequestInfo request;
1903 request.method = "GET";
bncce36dca22015-04-21 22:11:231904 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:101905 request.traffic_annotation =
1906 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:171907
danakj1fd259a02016-04-16 03:17:091908 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:581909 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:191910 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:171911
1912 MockRead data_reads[] = {
1913 MockRead("HTTP/1.0 200 OK\r\n"),
1914 MockRead("Connection: keep-alive\r\n"),
1915 MockRead("Content-Length: 100\r\n\r\n"),
1916 MockRead(SYNCHRONOUS, 0),
1917 };
Ryan Sleevib8d7ea02018-05-07 20:01:011918 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071919 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:171920
1921 TestCompletionCallback callback;
1922
tfarina42834112016-09-22 13:38:201923 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011924 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:171925
1926 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011927 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:171928
Victor Costan9c7302b2018-08-27 16:39:441929 scoped_refptr<IOBufferWithSize> io_buf(
1930 base::MakeRefCounted<IOBufferWithSize>(100));
[email protected]90499482013-06-01 00:39:501931 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:171932 if (rv == ERR_IO_PENDING)
1933 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011934 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:171935
1936 trans.reset();
fdoray92e35a72016-06-10 15:54:551937 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:171938 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
1939}
1940
[email protected]0b0bf032010-09-21 18:08:501941// Test that we correctly reuse a keep-alive connection after not explicitly
1942// reading the body.
bncd16676a2016-07-20 16:23:011943TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:131944 HttpRequestInfo request;
1945 request.method = "GET";
1946 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:101947 request.traffic_annotation =
1948 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:131949
vishal.b62985ca92015-04-17 08:45:511950 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071951 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091952 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271953
mmenkecc2298e2015-12-07 18:20:181954 const char* request_data =
1955 "GET / HTTP/1.1\r\n"
1956 "Host: www.foo.com\r\n"
1957 "Connection: keep-alive\r\n\r\n";
1958 MockWrite data_writes[] = {
1959 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
1960 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
1961 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
1962 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
1963 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
1964 };
1965
[email protected]0b0bf032010-09-21 18:08:501966 // Note that because all these reads happen in the same
1967 // StaticSocketDataProvider, it shows that the same socket is being reused for
1968 // all transactions.
mmenkecc2298e2015-12-07 18:20:181969 MockRead data_reads[] = {
1970 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
1971 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
1972 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
1973 MockRead(ASYNC, 7,
1974 "HTTP/1.1 302 Found\r\n"
1975 "Content-Length: 0\r\n\r\n"),
1976 MockRead(ASYNC, 9,
1977 "HTTP/1.1 302 Found\r\n"
1978 "Content-Length: 5\r\n\r\n"
1979 "hello"),
1980 MockRead(ASYNC, 11,
1981 "HTTP/1.1 301 Moved Permanently\r\n"
1982 "Content-Length: 0\r\n\r\n"),
1983 MockRead(ASYNC, 13,
1984 "HTTP/1.1 301 Moved Permanently\r\n"
1985 "Content-Length: 5\r\n\r\n"
1986 "hello"),
[email protected]fc31d6a42010-06-24 18:05:131987
mmenkecc2298e2015-12-07 18:20:181988 // In the next two rounds, IsConnectedAndIdle returns false, due to
1989 // the set_busy_before_sync_reads(true) call, while the
1990 // HttpNetworkTransaction is being shut down, but the socket is still
1991 // reuseable. See http://crbug.com/544255.
1992 MockRead(ASYNC, 15,
1993 "HTTP/1.1 200 Hunky-Dory\r\n"
1994 "Content-Length: 5\r\n\r\n"),
1995 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:131996
mmenkecc2298e2015-12-07 18:20:181997 MockRead(ASYNC, 18,
1998 "HTTP/1.1 200 Hunky-Dory\r\n"
1999 "Content-Length: 5\r\n\r\n"
2000 "he"),
2001 MockRead(SYNCHRONOUS, 19, "llo"),
2002
2003 // The body of the final request is actually read.
2004 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2005 MockRead(ASYNC, 22, "hello"),
2006 };
Ryan Sleevib8d7ea02018-05-07 20:01:012007 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182008 data.set_busy_before_sync_reads(true);
2009 session_deps_.socket_factory->AddSocketDataProvider(&data);
2010
2011 const int kNumUnreadBodies = arraysize(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502012 std::string response_lines[kNumUnreadBodies];
2013
mikecironef22f9812016-10-04 03:40:192014 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182015 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412016 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132017
Jeremy Roman0579ed62017-08-29 15:56:192018 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582019 session.get());
[email protected]fc31d6a42010-06-24 18:05:132020
tfarina42834112016-09-22 13:38:202021 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012022 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132023
[email protected]58e32bb2013-01-21 18:23:252024 LoadTimingInfo load_timing_info;
2025 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2026 if (i == 0) {
2027 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2028 first_socket_log_id = load_timing_info.socket_log_id;
2029 } else {
2030 TestLoadTimingReused(load_timing_info);
2031 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2032 }
2033
[email protected]fc31d6a42010-06-24 18:05:132034 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182035 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132036
mmenkecc2298e2015-12-07 18:20:182037 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502038 response_lines[i] = response->headers->GetStatusLine();
2039
mmenkecc2298e2015-12-07 18:20:182040 // Delete the transaction without reading the response bodies. Then spin
2041 // the message loop, so the response bodies are drained.
2042 trans.reset();
2043 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132044 }
[email protected]0b0bf032010-09-21 18:08:502045
2046 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182047 "HTTP/1.1 204 No Content",
2048 "HTTP/1.1 205 Reset Content",
2049 "HTTP/1.1 304 Not Modified",
2050 "HTTP/1.1 302 Found",
2051 "HTTP/1.1 302 Found",
2052 "HTTP/1.1 301 Moved Permanently",
2053 "HTTP/1.1 301 Moved Permanently",
2054 "HTTP/1.1 200 Hunky-Dory",
2055 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502056 };
2057
mostynb91e0da982015-01-20 19:17:272058 static_assert(kNumUnreadBodies == arraysize(kStatusLines),
2059 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502060
2061 for (int i = 0; i < kNumUnreadBodies; ++i)
2062 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2063
[email protected]49639fa2011-12-20 23:22:412064 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162065 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202066 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012067 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162068 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182069 ASSERT_TRUE(response);
2070 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502071 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2072 std::string response_data;
bnc691fda62016-08-12 00:43:162073 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012074 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502075 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132076}
2077
mmenke5f94fda2016-06-02 20:54:132078// Sockets that receive extra data after a response is complete should not be
2079// reused.
bncd16676a2016-07-20 16:23:012080TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132081 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2082 MockWrite data_writes1[] = {
2083 MockWrite("HEAD / 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_reads1[] = {
2089 MockRead("HTTP/1.1 200 OK\r\n"
2090 "Connection: keep-alive\r\n"
2091 "Content-Length: 22\r\n\r\n"
2092 "This server is borked."),
2093 };
2094
2095 MockWrite data_writes2[] = {
2096 MockWrite("GET /foo HTTP/1.1\r\n"
2097 "Host: www.borked.com\r\n"
2098 "Connection: keep-alive\r\n\r\n"),
2099 };
2100
2101 MockRead data_reads2[] = {
2102 MockRead("HTTP/1.1 200 OK\r\n"
2103 "Content-Length: 3\r\n\r\n"
2104 "foo"),
2105 };
Ryan Sleevib8d7ea02018-05-07 20:01:012106 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132107 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012108 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132109 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2110
2111 TestCompletionCallback callback;
2112 HttpRequestInfo request1;
2113 request1.method = "HEAD";
2114 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102115 request1.traffic_annotation =
2116 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132117
bnc87dcefc2017-05-25 12:47:582118 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192119 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202120 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012121 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132122
2123 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2124 ASSERT_TRUE(response1);
2125 ASSERT_TRUE(response1->headers);
2126 EXPECT_EQ(200, response1->headers->response_code());
2127 EXPECT_TRUE(response1->headers->IsKeepAlive());
2128
2129 std::string response_data1;
robpercival214763f2016-07-01 23:27:012130 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132131 EXPECT_EQ("", response_data1);
2132 // Deleting the transaction attempts to release the socket back into the
2133 // socket pool.
2134 trans1.reset();
2135
2136 HttpRequestInfo request2;
2137 request2.method = "GET";
2138 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102139 request2.traffic_annotation =
2140 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132141
bnc87dcefc2017-05-25 12:47:582142 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192143 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202144 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012145 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132146
2147 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2148 ASSERT_TRUE(response2);
2149 ASSERT_TRUE(response2->headers);
2150 EXPECT_EQ(200, response2->headers->response_code());
2151
2152 std::string response_data2;
robpercival214763f2016-07-01 23:27:012153 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132154 EXPECT_EQ("foo", response_data2);
2155}
2156
bncd16676a2016-07-20 16:23:012157TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132158 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2159 MockWrite data_writes1[] = {
2160 MockWrite("GET / HTTP/1.1\r\n"
2161 "Host: www.borked.com\r\n"
2162 "Connection: keep-alive\r\n\r\n"),
2163 };
2164
2165 MockRead data_reads1[] = {
2166 MockRead("HTTP/1.1 200 OK\r\n"
2167 "Connection: keep-alive\r\n"
2168 "Content-Length: 22\r\n\r\n"
2169 "This server is borked."
2170 "Bonus data!"),
2171 };
2172
2173 MockWrite data_writes2[] = {
2174 MockWrite("GET /foo HTTP/1.1\r\n"
2175 "Host: www.borked.com\r\n"
2176 "Connection: keep-alive\r\n\r\n"),
2177 };
2178
2179 MockRead data_reads2[] = {
2180 MockRead("HTTP/1.1 200 OK\r\n"
2181 "Content-Length: 3\r\n\r\n"
2182 "foo"),
2183 };
Ryan Sleevib8d7ea02018-05-07 20:01:012184 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132185 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012186 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132187 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2188
2189 TestCompletionCallback callback;
2190 HttpRequestInfo request1;
2191 request1.method = "GET";
2192 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102193 request1.traffic_annotation =
2194 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132195
bnc87dcefc2017-05-25 12:47:582196 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192197 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202198 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012199 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132200
2201 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2202 ASSERT_TRUE(response1);
2203 ASSERT_TRUE(response1->headers);
2204 EXPECT_EQ(200, response1->headers->response_code());
2205 EXPECT_TRUE(response1->headers->IsKeepAlive());
2206
2207 std::string response_data1;
robpercival214763f2016-07-01 23:27:012208 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132209 EXPECT_EQ("This server is borked.", response_data1);
2210 // Deleting the transaction attempts to release the socket back into the
2211 // socket pool.
2212 trans1.reset();
2213
2214 HttpRequestInfo request2;
2215 request2.method = "GET";
2216 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102217 request2.traffic_annotation =
2218 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132219
bnc87dcefc2017-05-25 12:47:582220 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192221 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202222 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012223 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132224
2225 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2226 ASSERT_TRUE(response2);
2227 ASSERT_TRUE(response2->headers);
2228 EXPECT_EQ(200, response2->headers->response_code());
2229
2230 std::string response_data2;
robpercival214763f2016-07-01 23:27:012231 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132232 EXPECT_EQ("foo", response_data2);
2233}
2234
bncd16676a2016-07-20 16:23:012235TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132236 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2237 MockWrite data_writes1[] = {
2238 MockWrite("GET / HTTP/1.1\r\n"
2239 "Host: www.borked.com\r\n"
2240 "Connection: keep-alive\r\n\r\n"),
2241 };
2242
2243 MockRead data_reads1[] = {
2244 MockRead("HTTP/1.1 200 OK\r\n"
2245 "Connection: keep-alive\r\n"
2246 "Transfer-Encoding: chunked\r\n\r\n"),
2247 MockRead("16\r\nThis server is borked.\r\n"),
2248 MockRead("0\r\n\r\nBonus data!"),
2249 };
2250
2251 MockWrite data_writes2[] = {
2252 MockWrite("GET /foo HTTP/1.1\r\n"
2253 "Host: www.borked.com\r\n"
2254 "Connection: keep-alive\r\n\r\n"),
2255 };
2256
2257 MockRead data_reads2[] = {
2258 MockRead("HTTP/1.1 200 OK\r\n"
2259 "Content-Length: 3\r\n\r\n"
2260 "foo"),
2261 };
Ryan Sleevib8d7ea02018-05-07 20:01:012262 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132263 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012264 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132265 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2266
2267 TestCompletionCallback callback;
2268 HttpRequestInfo request1;
2269 request1.method = "GET";
2270 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102271 request1.traffic_annotation =
2272 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132273
bnc87dcefc2017-05-25 12:47:582274 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192275 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202276 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012277 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132278
2279 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2280 ASSERT_TRUE(response1);
2281 ASSERT_TRUE(response1->headers);
2282 EXPECT_EQ(200, response1->headers->response_code());
2283 EXPECT_TRUE(response1->headers->IsKeepAlive());
2284
2285 std::string response_data1;
robpercival214763f2016-07-01 23:27:012286 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132287 EXPECT_EQ("This server is borked.", response_data1);
2288 // Deleting the transaction attempts to release the socket back into the
2289 // socket pool.
2290 trans1.reset();
2291
2292 HttpRequestInfo request2;
2293 request2.method = "GET";
2294 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e2018-02-07 07:41:102295 request2.traffic_annotation =
2296 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132297
bnc87dcefc2017-05-25 12:47:582298 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192299 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202300 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012301 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132302
2303 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2304 ASSERT_TRUE(response2);
2305 ASSERT_TRUE(response2->headers);
2306 EXPECT_EQ(200, response2->headers->response_code());
2307
2308 std::string response_data2;
robpercival214763f2016-07-01 23:27:012309 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132310 EXPECT_EQ("foo", response_data2);
2311}
2312
2313// This is a little different from the others - it tests the case that the
2314// HttpStreamParser doesn't know if there's extra data on a socket or not when
2315// the HttpNetworkTransaction is torn down, because the response body hasn't
2316// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012317TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132318 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2319 MockWrite data_writes1[] = {
2320 MockWrite("GET / HTTP/1.1\r\n"
2321 "Host: www.borked.com\r\n"
2322 "Connection: keep-alive\r\n\r\n"),
2323 };
2324
2325 MockRead data_reads1[] = {
2326 MockRead("HTTP/1.1 200 OK\r\n"
2327 "Connection: keep-alive\r\n"
2328 "Transfer-Encoding: chunked\r\n\r\n"),
2329 MockRead("16\r\nThis server is borked.\r\n"),
2330 MockRead("0\r\n\r\nBonus data!"),
2331 };
Ryan Sleevib8d7ea02018-05-07 20:01:012332 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132333 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2334
2335 TestCompletionCallback callback;
2336 HttpRequestInfo request1;
2337 request1.method = "GET";
2338 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e2018-02-07 07:41:102339 request1.traffic_annotation =
2340 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132341
bnc87dcefc2017-05-25 12:47:582342 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192343 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582344 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012345 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132346
bnc87dcefc2017-05-25 12:47:582347 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132348 ASSERT_TRUE(response1);
2349 ASSERT_TRUE(response1->headers);
2350 EXPECT_EQ(200, response1->headers->response_code());
2351 EXPECT_TRUE(response1->headers->IsKeepAlive());
2352
2353 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2354 // response body.
bnc87dcefc2017-05-25 12:47:582355 trans.reset();
mmenke5f94fda2016-06-02 20:54:132356
2357 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2358 // socket can't be reused, rather than returning it to the socket pool.
2359 base::RunLoop().RunUntilIdle();
2360
2361 // There should be no idle sockets in the pool.
2362 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2363}
2364
[email protected]038e9a32008-10-08 22:40:162365// Test the request-challenge-retry sequence for basic auth.
2366// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012367TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422368 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162369 request.method = "GET";
bncce36dca22015-04-21 22:11:232370 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102371 request.traffic_annotation =
2372 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162373
vishal.b62985ca92015-04-17 08:45:512374 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072375 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092376 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162377 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272378
[email protected]f9ee6b52008-11-08 06:46:232379 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232380 MockWrite(
2381 "GET / HTTP/1.1\r\n"
2382 "Host: www.example.org\r\n"
2383 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232384 };
2385
[email protected]038e9a32008-10-08 22:40:162386 MockRead data_reads1[] = {
2387 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2388 // Give a couple authenticate options (only the middle one is actually
2389 // supported).
[email protected]22927ad2009-09-21 19:56:192390 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162391 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2392 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2393 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2394 // Large content-length -- won't matter, as connection will be reset.
2395 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062396 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162397 };
2398
2399 // After calling trans->RestartWithAuth(), this is the request we should
2400 // be issuing -- the final header line contains the credentials.
2401 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232402 MockWrite(
2403 "GET / HTTP/1.1\r\n"
2404 "Host: www.example.org\r\n"
2405 "Connection: keep-alive\r\n"
2406 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162407 };
2408
2409 // Lastly, the server responds with the actual content.
2410 MockRead data_reads2[] = {
2411 MockRead("HTTP/1.0 200 OK\r\n"),
2412 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2413 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062414 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162415 };
2416
Ryan Sleevib8d7ea02018-05-07 20:01:012417 StaticSocketDataProvider data1(data_reads1, data_writes1);
2418 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:072419 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2420 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162421
[email protected]49639fa2011-12-20 23:22:412422 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162423
tfarina42834112016-09-22 13:38:202424 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012425 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162426
2427 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012428 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162429
[email protected]58e32bb2013-01-21 18:23:252430 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162431 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252432 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2433
Ryan Sleevib8d7ea02018-05-07 20:01:012434 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162435 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012436 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162437 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192438
bnc691fda62016-08-12 00:43:162439 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522440 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042441 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:162442
[email protected]49639fa2011-12-20 23:22:412443 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162444
bnc691fda62016-08-12 00:43:162445 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012446 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162447
2448 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012449 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162450
[email protected]58e32bb2013-01-21 18:23:252451 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162452 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252453 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2454 // The load timing after restart should have a new socket ID, and times after
2455 // those of the first load timing.
2456 EXPECT_LE(load_timing_info1.receive_headers_end,
2457 load_timing_info2.connect_timing.connect_start);
2458 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2459
Ryan Sleevib8d7ea02018-05-07 20:01:012460 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162461 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012462 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162463 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192464
bnc691fda62016-08-12 00:43:162465 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522466 ASSERT_TRUE(response);
2467 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:162468 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162469}
2470
ttuttled9dbc652015-09-29 20:00:592471// Test the request-challenge-retry sequence for basic auth.
2472// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012473TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592474 HttpRequestInfo request;
2475 request.method = "GET";
2476 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102477 request.traffic_annotation =
2478 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592479
2480 TestNetLog log;
2481 MockHostResolver* resolver = new MockHostResolver();
2482 session_deps_.net_log = &log;
2483 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092484 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162485 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592486
2487 resolver->rules()->ClearRules();
2488 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2489
2490 MockWrite data_writes1[] = {
2491 MockWrite("GET / HTTP/1.1\r\n"
2492 "Host: www.example.org\r\n"
2493 "Connection: keep-alive\r\n\r\n"),
2494 };
2495
2496 MockRead data_reads1[] = {
2497 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2498 // Give a couple authenticate options (only the middle one is actually
2499 // supported).
2500 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2501 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2502 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2503 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2504 // Large content-length -- won't matter, as connection will be reset.
2505 MockRead("Content-Length: 10000\r\n\r\n"),
2506 MockRead(SYNCHRONOUS, ERR_FAILED),
2507 };
2508
2509 // After calling trans->RestartWithAuth(), this is the request we should
2510 // be issuing -- the final header line contains the credentials.
2511 MockWrite data_writes2[] = {
2512 MockWrite("GET / HTTP/1.1\r\n"
2513 "Host: www.example.org\r\n"
2514 "Connection: keep-alive\r\n"
2515 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2516 };
2517
2518 // Lastly, the server responds with the actual content.
2519 MockRead data_reads2[] = {
2520 MockRead("HTTP/1.0 200 OK\r\n"),
2521 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2522 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2523 };
2524
Ryan Sleevib8d7ea02018-05-07 20:01:012525 StaticSocketDataProvider data1(data_reads1, data_writes1);
2526 StaticSocketDataProvider data2(data_reads2, data_writes2);
ttuttled9dbc652015-09-29 20:00:592527 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2528 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2529
2530 TestCompletionCallback callback1;
2531
bnc691fda62016-08-12 00:43:162532 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202533 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592534
2535 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162536 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592537 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2538
Ryan Sleevib8d7ea02018-05-07 20:01:012539 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162540 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012541 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162542 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592543
bnc691fda62016-08-12 00:43:162544 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592545 ASSERT_TRUE(response);
2546 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2547
2548 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162549 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592550 ASSERT_FALSE(endpoint.address().empty());
2551 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2552
2553 resolver->rules()->ClearRules();
2554 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2555
2556 TestCompletionCallback callback2;
2557
bnc691fda62016-08-12 00:43:162558 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592559 AuthCredentials(kFoo, kBar), callback2.callback())));
2560
2561 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162562 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592563 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2564 // The load timing after restart should have a new socket ID, and times after
2565 // those of the first load timing.
2566 EXPECT_LE(load_timing_info1.receive_headers_end,
2567 load_timing_info2.connect_timing.connect_start);
2568 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2569
Ryan Sleevib8d7ea02018-05-07 20:01:012570 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162571 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012572 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162573 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592574
bnc691fda62016-08-12 00:43:162575 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592576 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:522577 EXPECT_FALSE(response->auth_challenge);
ttuttled9dbc652015-09-29 20:00:592578 EXPECT_EQ(100, response->headers->GetContentLength());
2579
bnc691fda62016-08-12 00:43:162580 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592581 ASSERT_FALSE(endpoint.address().empty());
2582 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2583}
2584
David Benjamin83ddfb32018-03-30 01:07:522585// Test that, if the server requests auth indefinitely, HttpNetworkTransaction
2586// will eventually give up.
2587TEST_F(HttpNetworkTransactionTest, BasicAuthForever) {
2588 HttpRequestInfo request;
2589 request.method = "GET";
2590 request.url = GURL("http://www.example.org/");
2591 request.traffic_annotation =
2592 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2593
2594 TestNetLog log;
2595 session_deps_.net_log = &log;
2596 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2597 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2598
2599 MockWrite data_writes[] = {
2600 MockWrite("GET / HTTP/1.1\r\n"
2601 "Host: www.example.org\r\n"
2602 "Connection: keep-alive\r\n\r\n"),
2603 };
2604
2605 MockRead data_reads[] = {
2606 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2607 // Give a couple authenticate options (only the middle one is actually
2608 // supported).
2609 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2610 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2611 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2612 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2613 // Large content-length -- won't matter, as connection will be reset.
2614 MockRead("Content-Length: 10000\r\n\r\n"),
2615 MockRead(SYNCHRONOUS, ERR_FAILED),
2616 };
2617
2618 // After calling trans->RestartWithAuth(), this is the request we should
2619 // be issuing -- the final header line contains the credentials.
2620 MockWrite data_writes_restart[] = {
2621 MockWrite("GET / HTTP/1.1\r\n"
2622 "Host: www.example.org\r\n"
2623 "Connection: keep-alive\r\n"
2624 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2625 };
2626
Ryan Sleevib8d7ea02018-05-07 20:01:012627 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin83ddfb32018-03-30 01:07:522628 session_deps_.socket_factory->AddSocketDataProvider(&data);
2629
2630 TestCompletionCallback callback;
2631 int rv = callback.GetResult(
2632 trans.Start(&request, callback.callback(), NetLogWithSource()));
2633
2634 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_restarts;
2635 for (int i = 0; i < 32; i++) {
2636 // Check the previous response was a 401.
2637 EXPECT_THAT(rv, IsOk());
2638 const HttpResponseInfo* response = trans.GetResponseInfo();
2639 ASSERT_TRUE(response);
2640 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
2641
2642 data_restarts.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:012643 data_reads, data_writes_restart));
David Benjamin83ddfb32018-03-30 01:07:522644 session_deps_.socket_factory->AddSocketDataProvider(
2645 data_restarts.back().get());
2646 rv = callback.GetResult(trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2647 callback.callback()));
2648 }
2649
2650 // After too many tries, the transaction should have given up.
2651 EXPECT_THAT(rv, IsError(ERR_TOO_MANY_RETRIES));
2652}
2653
bncd16676a2016-07-20 16:23:012654TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462655 HttpRequestInfo request;
2656 request.method = "GET";
bncce36dca22015-04-21 22:11:232657 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292658 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:102659 request.traffic_annotation =
2660 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462661
danakj1fd259a02016-04-16 03:17:092662 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162663 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272664
[email protected]861fcd52009-08-26 02:33:462665 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232666 MockWrite(
2667 "GET / HTTP/1.1\r\n"
2668 "Host: www.example.org\r\n"
2669 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462670 };
2671
2672 MockRead data_reads[] = {
2673 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2674 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2675 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2676 // Large content-length -- won't matter, as connection will be reset.
2677 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062678 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462679 };
2680
Ryan Sleevib8d7ea02018-05-07 20:01:012681 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:072682 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412683 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462684
tfarina42834112016-09-22 13:38:202685 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012686 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462687
2688 rv = callback.WaitForResult();
2689 EXPECT_EQ(0, rv);
2690
Ryan Sleevib8d7ea02018-05-07 20:01:012691 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:162692 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012693 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:162694 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192695
bnc691fda62016-08-12 00:43:162696 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522697 ASSERT_TRUE(response);
2698 EXPECT_FALSE(response->auth_challenge);
[email protected]861fcd52009-08-26 02:33:462699}
2700
[email protected]2d2697f92009-02-18 21:00:322701// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2702// connection.
bncd16676a2016-07-20 16:23:012703TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182704 // On the second pass, the body read of the auth challenge is synchronous, so
2705 // IsConnectedAndIdle returns false. The socket should still be drained and
2706 // reused. See http://crbug.com/544255.
2707 for (int i = 0; i < 2; ++i) {
2708 HttpRequestInfo request;
2709 request.method = "GET";
2710 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102711 request.traffic_annotation =
2712 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322713
mmenkecc2298e2015-12-07 18:20:182714 TestNetLog log;
2715 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092716 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272717
mmenkecc2298e2015-12-07 18:20:182718 MockWrite data_writes[] = {
2719 MockWrite(ASYNC, 0,
2720 "GET / HTTP/1.1\r\n"
2721 "Host: www.example.org\r\n"
2722 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322723
bnc691fda62016-08-12 00:43:162724 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182725 // be issuing -- the final header line contains the credentials.
2726 MockWrite(ASYNC, 6,
2727 "GET / HTTP/1.1\r\n"
2728 "Host: www.example.org\r\n"
2729 "Connection: keep-alive\r\n"
2730 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2731 };
[email protected]2d2697f92009-02-18 21:00:322732
mmenkecc2298e2015-12-07 18:20:182733 MockRead data_reads[] = {
2734 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2735 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2736 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2737 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2738 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322739
mmenkecc2298e2015-12-07 18:20:182740 // Lastly, the server responds with the actual content.
2741 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2742 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2743 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2744 MockRead(ASYNC, 10, "Hello"),
2745 };
[email protected]2d2697f92009-02-18 21:00:322746
Ryan Sleevib8d7ea02018-05-07 20:01:012747 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182748 data.set_busy_before_sync_reads(true);
2749 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462750
mmenkecc2298e2015-12-07 18:20:182751 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322752
bnc691fda62016-08-12 00:43:162753 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202754 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012755 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322756
mmenkecc2298e2015-12-07 18:20:182757 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162758 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182759 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322760
bnc691fda62016-08-12 00:43:162761 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182762 ASSERT_TRUE(response);
2763 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322764
mmenkecc2298e2015-12-07 18:20:182765 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:252766
bnc691fda62016-08-12 00:43:162767 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2768 callback2.callback());
robpercival214763f2016-07-01 23:27:012769 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322770
mmenkecc2298e2015-12-07 18:20:182771 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162772 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:182773 TestLoadTimingReused(load_timing_info2);
2774 // The load timing after restart should have the same socket ID, and times
2775 // those of the first load timing.
2776 EXPECT_LE(load_timing_info1.receive_headers_end,
2777 load_timing_info2.send_start);
2778 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:322779
bnc691fda62016-08-12 00:43:162780 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182781 ASSERT_TRUE(response);
2782 EXPECT_FALSE(response->auth_challenge);
2783 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322784
mmenkecc2298e2015-12-07 18:20:182785 std::string response_data;
bnc691fda62016-08-12 00:43:162786 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:322787
Ryan Sleevib8d7ea02018-05-07 20:01:012788 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:162789 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012790 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:162791 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:182792 }
[email protected]2d2697f92009-02-18 21:00:322793}
2794
2795// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2796// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:012797TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:422798 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322799 request.method = "GET";
bncce36dca22015-04-21 22:11:232800 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102801 request.traffic_annotation =
2802 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322803
danakj1fd259a02016-04-16 03:17:092804 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272805
[email protected]2d2697f92009-02-18 21:00:322806 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162807 MockWrite("GET / HTTP/1.1\r\n"
2808 "Host: www.example.org\r\n"
2809 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322810
bnc691fda62016-08-12 00:43:162811 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232812 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162813 MockWrite("GET / HTTP/1.1\r\n"
2814 "Host: www.example.org\r\n"
2815 "Connection: keep-alive\r\n"
2816 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322817 };
2818
[email protected]2d2697f92009-02-18 21:00:322819 MockRead data_reads1[] = {
2820 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2821 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:312822 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:322823
2824 // Lastly, the server responds with the actual content.
2825 MockRead("HTTP/1.1 200 OK\r\n"),
2826 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502827 MockRead("Content-Length: 5\r\n\r\n"),
2828 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322829 };
2830
[email protected]2d0a4f92011-05-05 16:38:462831 // An incorrect reconnect would cause this to be read.
2832 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062833 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462834 };
2835
Ryan Sleevib8d7ea02018-05-07 20:01:012836 StaticSocketDataProvider data1(data_reads1, data_writes1);
2837 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072838 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2839 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322840
[email protected]49639fa2011-12-20 23:22:412841 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322842
bnc691fda62016-08-12 00:43:162843 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202844 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012845 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322846
2847 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012848 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322849
bnc691fda62016-08-12 00:43:162850 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522851 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042852 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322853
[email protected]49639fa2011-12-20 23:22:412854 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322855
bnc691fda62016-08-12 00:43:162856 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012857 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322858
2859 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012860 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322861
bnc691fda62016-08-12 00:43:162862 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522863 ASSERT_TRUE(response);
2864 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502865 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322866}
2867
2868// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2869// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:012870TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:422871 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:322872 request.method = "GET";
bncce36dca22015-04-21 22:11:232873 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102874 request.traffic_annotation =
2875 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322876
danakj1fd259a02016-04-16 03:17:092877 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272878
[email protected]2d2697f92009-02-18 21:00:322879 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:162880 MockWrite("GET / HTTP/1.1\r\n"
2881 "Host: www.example.org\r\n"
2882 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322883
bnc691fda62016-08-12 00:43:162884 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:232885 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:162886 MockWrite("GET / HTTP/1.1\r\n"
2887 "Host: www.example.org\r\n"
2888 "Connection: keep-alive\r\n"
2889 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322890 };
2891
2892 // Respond with 5 kb of response body.
2893 std::string large_body_string("Unauthorized");
2894 large_body_string.append(5 * 1024, ' ');
2895 large_body_string.append("\r\n");
2896
2897 MockRead data_reads1[] = {
2898 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2899 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2900 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2901 // 5134 = 12 + 5 * 1024 + 2
2902 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062903 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:322904
2905 // Lastly, the server responds with the actual content.
2906 MockRead("HTTP/1.1 200 OK\r\n"),
2907 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502908 MockRead("Content-Length: 5\r\n\r\n"),
2909 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:322910 };
2911
[email protected]2d0a4f92011-05-05 16:38:462912 // An incorrect reconnect would cause this to be read.
2913 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:062914 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:462915 };
2916
Ryan Sleevib8d7ea02018-05-07 20:01:012917 StaticSocketDataProvider data1(data_reads1, data_writes1);
2918 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072919 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2920 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:322921
[email protected]49639fa2011-12-20 23:22:412922 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322923
bnc691fda62016-08-12 00:43:162924 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202925 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012926 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322927
2928 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012929 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322930
bnc691fda62016-08-12 00:43:162931 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522932 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:042933 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:322934
[email protected]49639fa2011-12-20 23:22:412935 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:322936
bnc691fda62016-08-12 00:43:162937 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012938 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:322939
2940 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012941 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:322942
bnc691fda62016-08-12 00:43:162943 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522944 ASSERT_TRUE(response);
2945 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:502946 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:322947}
2948
2949// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:312950// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:012951TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:312952 HttpRequestInfo request;
2953 request.method = "GET";
bncce36dca22015-04-21 22:11:232954 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:102955 request.traffic_annotation =
2956 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:312957
danakj1fd259a02016-04-16 03:17:092958 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272959
[email protected]11203f012009-11-12 23:02:312960 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232961 MockWrite(
2962 "GET / HTTP/1.1\r\n"
2963 "Host: www.example.org\r\n"
2964 "Connection: keep-alive\r\n\r\n"),
2965 // This simulates the seemingly successful write to a closed connection
2966 // if the bug is not fixed.
2967 MockWrite(
2968 "GET / HTTP/1.1\r\n"
2969 "Host: www.example.org\r\n"
2970 "Connection: keep-alive\r\n"
2971 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312972 };
2973
2974 MockRead data_reads1[] = {
2975 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
2976 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2977 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2978 MockRead("Content-Length: 14\r\n\r\n"),
2979 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:062980 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:312981 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:062982 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:312983 };
2984
bnc691fda62016-08-12 00:43:162985 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:312986 // be issuing -- the final header line contains the credentials.
2987 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232988 MockWrite(
2989 "GET / HTTP/1.1\r\n"
2990 "Host: www.example.org\r\n"
2991 "Connection: keep-alive\r\n"
2992 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:312993 };
2994
2995 // Lastly, the server responds with the actual content.
2996 MockRead data_reads2[] = {
2997 MockRead("HTTP/1.1 200 OK\r\n"),
2998 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:502999 MockRead("Content-Length: 5\r\n\r\n"),
3000 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:313001 };
3002
Ryan Sleevib8d7ea02018-05-07 20:01:013003 StaticSocketDataProvider data1(data_reads1, data_writes1);
3004 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:073005 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3006 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:313007
[email protected]49639fa2011-12-20 23:22:413008 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:313009
bnc691fda62016-08-12 00:43:163010 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203011 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013012 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313013
3014 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013015 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313016
bnc691fda62016-08-12 00:43:163017 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523018 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:043019 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]11203f012009-11-12 23:02:313020
[email protected]49639fa2011-12-20 23:22:413021 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313022
bnc691fda62016-08-12 00:43:163023 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013024 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313025
3026 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013027 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313028
bnc691fda62016-08-12 00:43:163029 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523030 ASSERT_TRUE(response);
3031 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503032 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313033}
3034
[email protected]394816e92010-08-03 07:38:593035// Test the request-challenge-retry sequence for basic auth, over a connection
3036// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013037TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013038 HttpRequestInfo request;
3039 request.method = "GET";
bncce36dca22015-04-21 22:11:233040 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013041 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293042 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103043 request.traffic_annotation =
3044 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013045
3046 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593047 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493048 ProxyResolutionService::CreateFixedFromPacResult(
3049 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513050 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013051 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093052 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013053
3054 // Since we have proxy, should try to establish tunnel.
3055 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543056 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173057 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543058 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013059 };
3060
mmenkee71e15332015-10-07 16:39:543061 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013062 // connection.
3063 MockRead data_reads1[] = {
3064 // No credentials.
3065 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3066 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543067 };
ttuttle34f63b52015-03-05 04:33:013068
mmenkee71e15332015-10-07 16:39:543069 // Since the first connection couldn't be reused, need to establish another
3070 // once given credentials.
3071 MockWrite data_writes2[] = {
3072 // After calling trans->RestartWithAuth(), this is the request we should
3073 // be issuing -- the final header line contains the credentials.
3074 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173075 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543076 "Proxy-Connection: keep-alive\r\n"
3077 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3078
3079 MockWrite("GET / HTTP/1.1\r\n"
3080 "Host: www.example.org\r\n"
3081 "Connection: keep-alive\r\n\r\n"),
3082 };
3083
3084 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013085 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3086
3087 MockRead("HTTP/1.1 200 OK\r\n"),
3088 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3089 MockRead("Content-Length: 5\r\n\r\n"),
3090 MockRead(SYNCHRONOUS, "hello"),
3091 };
3092
Ryan Sleevib8d7ea02018-05-07 20:01:013093 StaticSocketDataProvider data1(data_reads1, data_writes1);
ttuttle34f63b52015-03-05 04:33:013094 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013095 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543096 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013097 SSLSocketDataProvider ssl(ASYNC, OK);
3098 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3099
3100 TestCompletionCallback callback1;
3101
bnc87dcefc2017-05-25 12:47:583102 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193103 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013104
3105 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013106 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013107
3108 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013109 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463110 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013111 log.GetEntries(&entries);
3112 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003113 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3114 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013115 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003116 entries, pos,
3117 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3118 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013119
3120 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523121 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013122 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523123 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013124 EXPECT_EQ(407, response->headers->response_code());
3125 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3126 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3127
3128 LoadTimingInfo load_timing_info;
3129 // CONNECT requests and responses are handled at the connect job level, so
3130 // the transaction does not yet have a connection.
3131 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3132
3133 TestCompletionCallback callback2;
3134
3135 rv =
3136 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013137 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013138
3139 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013140 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013141
3142 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523143 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013144
3145 EXPECT_TRUE(response->headers->IsKeepAlive());
3146 EXPECT_EQ(200, response->headers->response_code());
3147 EXPECT_EQ(5, response->headers->GetContentLength());
3148 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3149
3150 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523151 EXPECT_FALSE(response->auth_challenge);
ttuttle34f63b52015-03-05 04:33:013152
3153 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3154 TestLoadTimingNotReusedWithPac(load_timing_info,
3155 CONNECT_TIMING_HAS_SSL_TIMES);
3156
3157 trans.reset();
3158 session->CloseAllConnections();
3159}
3160
3161// Test the request-challenge-retry sequence for basic auth, over a connection
3162// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013163TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593164 HttpRequestInfo request;
3165 request.method = "GET";
bncce36dca22015-04-21 22:11:233166 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593167 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293168 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103169 request.traffic_annotation =
3170 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]394816e92010-08-03 07:38:593171
[email protected]cb9bf6ca2011-01-28 13:15:273172 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593173 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493174 ProxyResolutionService::CreateFixedFromPacResult(
3175 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513176 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073177 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093178 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273179
[email protected]394816e92010-08-03 07:38:593180 // Since we have proxy, should try to establish tunnel.
3181 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543182 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173183 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543184 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113185 };
3186
mmenkee71e15332015-10-07 16:39:543187 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083188 // connection.
3189 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543190 // No credentials.
3191 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3192 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3193 MockRead("Proxy-Connection: close\r\n\r\n"),
3194 };
mmenkee0b5c882015-08-26 20:29:113195
mmenkee71e15332015-10-07 16:39:543196 MockWrite data_writes2[] = {
3197 // After calling trans->RestartWithAuth(), this is the request we should
3198 // be issuing -- the final header line contains the credentials.
3199 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173200 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543201 "Proxy-Connection: keep-alive\r\n"
3202 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083203
mmenkee71e15332015-10-07 16:39:543204 MockWrite("GET / HTTP/1.1\r\n"
3205 "Host: www.example.org\r\n"
3206 "Connection: keep-alive\r\n\r\n"),
3207 };
3208
3209 MockRead data_reads2[] = {
3210 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3211
3212 MockRead("HTTP/1.1 200 OK\r\n"),
3213 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3214 MockRead("Content-Length: 5\r\n\r\n"),
3215 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593216 };
3217
Ryan Sleevib8d7ea02018-05-07 20:01:013218 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073219 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013220 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543221 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063222 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073223 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593224
[email protected]49639fa2011-12-20 23:22:413225 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593226
bnc87dcefc2017-05-25 12:47:583227 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193228 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503229
[email protected]49639fa2011-12-20 23:22:413230 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013231 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593232
3233 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013234 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463235 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403236 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593237 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003238 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3239 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593240 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403241 entries, pos,
mikecirone8b85c432016-09-08 19:11:003242 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3243 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593244
3245 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523246 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013247 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523248 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593249 EXPECT_EQ(407, response->headers->response_code());
3250 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043251 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]394816e92010-08-03 07:38:593252
[email protected]029c83b62013-01-24 05:28:203253 LoadTimingInfo load_timing_info;
3254 // CONNECT requests and responses are handled at the connect job level, so
3255 // the transaction does not yet have a connection.
3256 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3257
[email protected]49639fa2011-12-20 23:22:413258 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593259
[email protected]49639fa2011-12-20 23:22:413260 rv = trans->RestartWithAuth(
3261 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013262 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593263
3264 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013265 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593266
3267 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523268 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593269
3270 EXPECT_TRUE(response->headers->IsKeepAlive());
3271 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503272 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593273 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3274
3275 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:523276 EXPECT_FALSE(response->auth_challenge);
[email protected]0b0bf032010-09-21 18:08:503277
[email protected]029c83b62013-01-24 05:28:203278 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3279 TestLoadTimingNotReusedWithPac(load_timing_info,
3280 CONNECT_TIMING_HAS_SSL_TIMES);
3281
[email protected]0b0bf032010-09-21 18:08:503282 trans.reset();
[email protected]102e27c2011-02-23 01:01:313283 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593284}
3285
[email protected]11203f012009-11-12 23:02:313286// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013287// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013288TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233289 // On the second pass, the body read of the auth challenge is synchronous, so
3290 // IsConnectedAndIdle returns false. The socket should still be drained and
3291 // reused. See http://crbug.com/544255.
3292 for (int i = 0; i < 2; ++i) {
3293 HttpRequestInfo request;
3294 request.method = "GET";
3295 request.url = GURL("https://www.example.org/");
3296 // Ensure that proxy authentication is attempted even
3297 // when the no authentication data flag is set.
3298 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103299 request.traffic_annotation =
3300 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013301
mmenked39192ee2015-12-09 00:57:233302 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593303 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493304 ProxyResolutionService::CreateFixed("myproxy:70",
3305 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233306 BoundTestNetLog log;
3307 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093308 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013309
bnc691fda62016-08-12 00:43:163310 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013311
mmenked39192ee2015-12-09 00:57:233312 // Since we have proxy, should try to establish tunnel.
3313 MockWrite data_writes1[] = {
3314 MockWrite(ASYNC, 0,
3315 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3316 "Host: www.example.org:443\r\n"
3317 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013318
bnc691fda62016-08-12 00:43:163319 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233320 // be issuing -- the final header line contains the credentials.
3321 MockWrite(ASYNC, 3,
3322 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3323 "Host: www.example.org:443\r\n"
3324 "Proxy-Connection: keep-alive\r\n"
3325 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3326 };
ttuttle34f63b52015-03-05 04:33:013327
mmenked39192ee2015-12-09 00:57:233328 // The proxy responds to the connect with a 407, using a persistent
3329 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3330 MockRead data_reads1[] = {
3331 // No credentials.
3332 MockRead(ASYNC, 1,
3333 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3334 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3335 "Proxy-Connection: keep-alive\r\n"
3336 "Content-Length: 10\r\n\r\n"),
3337 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013338
mmenked39192ee2015-12-09 00:57:233339 // Wrong credentials (wrong password).
3340 MockRead(ASYNC, 4,
3341 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3342 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3343 "Proxy-Connection: keep-alive\r\n"
3344 "Content-Length: 10\r\n\r\n"),
3345 // No response body because the test stops reading here.
3346 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3347 };
ttuttle34f63b52015-03-05 04:33:013348
Ryan Sleevib8d7ea02018-05-07 20:01:013349 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233350 data1.set_busy_before_sync_reads(true);
3351 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013352
mmenked39192ee2015-12-09 00:57:233353 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013354
bnc691fda62016-08-12 00:43:163355 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013356 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013357
mmenked39192ee2015-12-09 00:57:233358 TestNetLogEntry::List entries;
3359 log.GetEntries(&entries);
3360 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003361 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3362 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233363 ExpectLogContainsSomewhere(
3364 entries, pos,
mikecirone8b85c432016-09-08 19:11:003365 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3366 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013367
bnc691fda62016-08-12 00:43:163368 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233369 ASSERT_TRUE(response);
3370 ASSERT_TRUE(response->headers);
3371 EXPECT_TRUE(response->headers->IsKeepAlive());
3372 EXPECT_EQ(407, response->headers->response_code());
3373 EXPECT_EQ(10, response->headers->GetContentLength());
3374 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3375 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013376
mmenked39192ee2015-12-09 00:57:233377 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013378
mmenked39192ee2015-12-09 00:57:233379 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163380 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3381 callback2.callback());
robpercival214763f2016-07-01 23:27:013382 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013383
bnc691fda62016-08-12 00:43:163384 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233385 ASSERT_TRUE(response);
3386 ASSERT_TRUE(response->headers);
3387 EXPECT_TRUE(response->headers->IsKeepAlive());
3388 EXPECT_EQ(407, response->headers->response_code());
3389 EXPECT_EQ(10, response->headers->GetContentLength());
3390 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
3391 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
ttuttle34f63b52015-03-05 04:33:013392
mmenked39192ee2015-12-09 00:57:233393 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3394 // out of scope.
3395 session->CloseAllConnections();
3396 }
ttuttle34f63b52015-03-05 04:33:013397}
3398
3399// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3400// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013401TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233402 // On the second pass, the body read of the auth challenge is synchronous, so
3403 // IsConnectedAndIdle returns false. The socket should still be drained and
3404 // reused. See http://crbug.com/544255.
3405 for (int i = 0; i < 2; ++i) {
3406 HttpRequestInfo request;
3407 request.method = "GET";
3408 request.url = GURL("https://www.example.org/");
3409 // Ensure that proxy authentication is attempted even
3410 // when the no authentication data flag is set.
3411 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103412 request.traffic_annotation =
3413 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233414
3415 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593416 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493417 ProxyResolutionService::CreateFixed("myproxy:70",
3418 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233419 BoundTestNetLog log;
3420 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093421 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233422
bnc691fda62016-08-12 00:43:163423 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233424
3425 // Since we have proxy, should try to establish tunnel.
3426 MockWrite data_writes1[] = {
3427 MockWrite(ASYNC, 0,
3428 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3429 "Host: www.example.org:443\r\n"
3430 "Proxy-Connection: keep-alive\r\n\r\n"),
3431
bnc691fda62016-08-12 00:43:163432 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233433 // be issuing -- the final header line contains the credentials.
3434 MockWrite(ASYNC, 3,
3435 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3436 "Host: www.example.org:443\r\n"
3437 "Proxy-Connection: keep-alive\r\n"
3438 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3439 };
3440
3441 // The proxy responds to the connect with a 407, using a persistent
3442 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3443 MockRead data_reads1[] = {
3444 // No credentials.
3445 MockRead(ASYNC, 1,
3446 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3447 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3448 "Content-Length: 10\r\n\r\n"),
3449 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3450
3451 // Wrong credentials (wrong password).
3452 MockRead(ASYNC, 4,
3453 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3454 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3455 "Content-Length: 10\r\n\r\n"),
3456 // No response body because the test stops reading here.
3457 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3458 };
3459
Ryan Sleevib8d7ea02018-05-07 20:01:013460 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233461 data1.set_busy_before_sync_reads(true);
3462 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3463
3464 TestCompletionCallback callback1;
3465
bnc691fda62016-08-12 00:43:163466 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013467 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233468
3469 TestNetLogEntry::List entries;
3470 log.GetEntries(&entries);
3471 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003472 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3473 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233474 ExpectLogContainsSomewhere(
3475 entries, pos,
mikecirone8b85c432016-09-08 19:11:003476 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3477 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233478
bnc691fda62016-08-12 00:43:163479 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233480 ASSERT_TRUE(response);
3481 ASSERT_TRUE(response->headers);
3482 EXPECT_TRUE(response->headers->IsKeepAlive());
3483 EXPECT_EQ(407, response->headers->response_code());
3484 EXPECT_EQ(10, response->headers->GetContentLength());
3485 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3486 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3487
3488 TestCompletionCallback callback2;
3489
3490 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163491 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3492 callback2.callback());
robpercival214763f2016-07-01 23:27:013493 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233494
bnc691fda62016-08-12 00:43:163495 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233496 ASSERT_TRUE(response);
3497 ASSERT_TRUE(response->headers);
3498 EXPECT_TRUE(response->headers->IsKeepAlive());
3499 EXPECT_EQ(407, response->headers->response_code());
3500 EXPECT_EQ(10, response->headers->GetContentLength());
3501 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3502 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3503
3504 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3505 // out of scope.
3506 session->CloseAllConnections();
3507 }
3508}
3509
3510// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3511// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3512// the case the server sends extra data on the original socket, so it can't be
3513// reused.
bncd16676a2016-07-20 16:23:013514TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273515 HttpRequestInfo request;
3516 request.method = "GET";
bncce36dca22015-04-21 22:11:233517 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273518 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293519 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103520 request.traffic_annotation =
3521 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273522
[email protected]2d2697f92009-02-18 21:00:323523 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593524 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493525 ProxyResolutionService::CreateFixedFromPacResult(
3526 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513527 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073528 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093529 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323530
[email protected]2d2697f92009-02-18 21:00:323531 // Since we have proxy, should try to establish tunnel.
3532 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233533 MockWrite(ASYNC, 0,
3534 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173535 "Host: www.example.org:443\r\n"
3536 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233537 };
[email protected]2d2697f92009-02-18 21:00:323538
mmenked39192ee2015-12-09 00:57:233539 // The proxy responds to the connect with a 407, using a persistent, but sends
3540 // extra data, so the socket cannot be reused.
3541 MockRead data_reads1[] = {
3542 // No credentials.
3543 MockRead(ASYNC, 1,
3544 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3545 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3546 "Content-Length: 10\r\n\r\n"),
3547 MockRead(SYNCHRONOUS, 2, "0123456789"),
3548 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3549 };
3550
3551 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233552 // After calling trans->RestartWithAuth(), this is the request we should
3553 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233554 MockWrite(ASYNC, 0,
3555 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173556 "Host: www.example.org:443\r\n"
3557 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233558 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3559
3560 MockWrite(ASYNC, 2,
3561 "GET / HTTP/1.1\r\n"
3562 "Host: www.example.org\r\n"
3563 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323564 };
3565
mmenked39192ee2015-12-09 00:57:233566 MockRead data_reads2[] = {
3567 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323568
mmenked39192ee2015-12-09 00:57:233569 MockRead(ASYNC, 3,
3570 "HTTP/1.1 200 OK\r\n"
3571 "Content-Type: text/html; charset=iso-8859-1\r\n"
3572 "Content-Length: 5\r\n\r\n"),
3573 // No response body because the test stops reading here.
3574 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323575 };
3576
Ryan Sleevib8d7ea02018-05-07 20:01:013577 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233578 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073579 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013580 SequencedSocketData data2(data_reads2, data_writes2);
mmenked39192ee2015-12-09 00:57:233581 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3582 SSLSocketDataProvider ssl(ASYNC, OK);
3583 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323584
[email protected]49639fa2011-12-20 23:22:413585 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323586
bnc87dcefc2017-05-25 12:47:583587 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193588 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323589
mmenked39192ee2015-12-09 00:57:233590 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013591 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233592
mmenke43758e62015-05-04 21:09:463593 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403594 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393595 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003596 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3597 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393598 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403599 entries, pos,
mikecirone8b85c432016-09-08 19:11:003600 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3601 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323602
[email protected]1c773ea12009-04-28 19:58:423603 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243604 ASSERT_TRUE(response);
3605 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323606 EXPECT_TRUE(response->headers->IsKeepAlive());
3607 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423608 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]79cb5c12011-09-12 13:12:043609 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]2d2697f92009-02-18 21:00:323610
mmenked39192ee2015-12-09 00:57:233611 LoadTimingInfo load_timing_info;
3612 // CONNECT requests and responses are handled at the connect job level, so
3613 // the transaction does not yet have a connection.
3614 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3615
[email protected]49639fa2011-12-20 23:22:413616 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323617
mmenked39192ee2015-12-09 00:57:233618 rv =
3619 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013620 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323621
[email protected]2d2697f92009-02-18 21:00:323622 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233623 EXPECT_EQ(200, response->headers->response_code());
3624 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423625 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133626
mmenked39192ee2015-12-09 00:57:233627 // The password prompt info should not be set.
3628 EXPECT_FALSE(response->auth_challenge);
3629
3630 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3631 TestLoadTimingNotReusedWithPac(load_timing_info,
3632 CONNECT_TIMING_HAS_SSL_TIMES);
3633
3634 trans.reset();
[email protected]102e27c2011-02-23 01:01:313635 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323636}
3637
mmenkee71e15332015-10-07 16:39:543638// Test the case a proxy closes a socket while the challenge body is being
3639// drained.
bncd16676a2016-07-20 16:23:013640TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543641 HttpRequestInfo request;
3642 request.method = "GET";
3643 request.url = GURL("https://www.example.org/");
3644 // Ensure that proxy authentication is attempted even
3645 // when the no authentication data flag is set.
3646 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:103647 request.traffic_annotation =
3648 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543649
3650 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493651 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3652 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:093653 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543654
bnc691fda62016-08-12 00:43:163655 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543656
3657 // Since we have proxy, should try to establish tunnel.
3658 MockWrite data_writes1[] = {
3659 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173660 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543661 "Proxy-Connection: keep-alive\r\n\r\n"),
3662 };
3663
3664 // The proxy responds to the connect with a 407, using a persistent
3665 // connection.
3666 MockRead data_reads1[] = {
3667 // No credentials.
3668 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3669 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3670 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3671 // Server hands up in the middle of the body.
3672 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3673 };
3674
3675 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163676 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543677 // be issuing -- the final header line contains the credentials.
3678 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173679 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543680 "Proxy-Connection: keep-alive\r\n"
3681 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3682
3683 MockWrite("GET / HTTP/1.1\r\n"
3684 "Host: www.example.org\r\n"
3685 "Connection: keep-alive\r\n\r\n"),
3686 };
3687
3688 MockRead data_reads2[] = {
3689 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3690
3691 MockRead("HTTP/1.1 200 OK\r\n"),
3692 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3693 MockRead("Content-Length: 5\r\n\r\n"),
3694 MockRead(SYNCHRONOUS, "hello"),
3695 };
3696
Ryan Sleevib8d7ea02018-05-07 20:01:013697 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenkee71e15332015-10-07 16:39:543698 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013699 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543700 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3701 SSLSocketDataProvider ssl(ASYNC, OK);
3702 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3703
3704 TestCompletionCallback callback;
3705
tfarina42834112016-09-22 13:38:203706 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013707 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543708
bnc691fda62016-08-12 00:43:163709 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543710 ASSERT_TRUE(response);
3711 ASSERT_TRUE(response->headers);
3712 EXPECT_TRUE(response->headers->IsKeepAlive());
3713 EXPECT_EQ(407, response->headers->response_code());
3714 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
3715
bnc691fda62016-08-12 00:43:163716 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013717 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543718
bnc691fda62016-08-12 00:43:163719 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543720 ASSERT_TRUE(response);
3721 ASSERT_TRUE(response->headers);
3722 EXPECT_TRUE(response->headers->IsKeepAlive());
3723 EXPECT_EQ(200, response->headers->response_code());
3724 std::string body;
bnc691fda62016-08-12 00:43:163725 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543726 EXPECT_EQ("hello", body);
3727}
3728
[email protected]a8e9b162009-03-12 00:06:443729// Test that we don't read the response body when we fail to establish a tunnel,
3730// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013731TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273732 HttpRequestInfo request;
3733 request.method = "GET";
bncce36dca22015-04-21 22:11:233734 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103735 request.traffic_annotation =
3736 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273737
[email protected]a8e9b162009-03-12 00:06:443738 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493739 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3740 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a8e9b162009-03-12 00:06:443741
danakj1fd259a02016-04-16 03:17:093742 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443743
bnc691fda62016-08-12 00:43:163744 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443745
[email protected]a8e9b162009-03-12 00:06:443746 // Since we have proxy, should try to establish tunnel.
3747 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173748 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3749 "Host: www.example.org:443\r\n"
3750 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443751 };
3752
3753 // The proxy responds to the connect with a 407.
3754 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243755 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3756 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3757 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233758 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:243759 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:443760 };
3761
Ryan Sleevib8d7ea02018-05-07 20:01:013762 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:073763 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:443764
[email protected]49639fa2011-12-20 23:22:413765 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:443766
tfarina42834112016-09-22 13:38:203767 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013768 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:443769
3770 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013771 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:443772
bnc691fda62016-08-12 00:43:163773 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243774 ASSERT_TRUE(response);
3775 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:443776 EXPECT_TRUE(response->headers->IsKeepAlive());
3777 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423778 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:443779
3780 std::string response_data;
bnc691fda62016-08-12 00:43:163781 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013782 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:183783
3784 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:313785 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:443786}
3787
ttuttle7933c112015-01-06 00:55:243788// Test that we don't pass extraneous headers from the proxy's response to the
3789// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:013790TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:243791 HttpRequestInfo request;
3792 request.method = "GET";
bncce36dca22015-04-21 22:11:233793 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103794 request.traffic_annotation =
3795 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:243796
3797 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493798 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3799 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:243800
danakj1fd259a02016-04-16 03:17:093801 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:243802
bnc691fda62016-08-12 00:43:163803 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:243804
3805 // Since we have proxy, should try to establish tunnel.
3806 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173807 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3808 "Host: www.example.org:443\r\n"
3809 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:243810 };
3811
3812 // The proxy responds to the connect with a 407.
3813 MockRead data_reads[] = {
3814 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3815 MockRead("X-Foo: bar\r\n"),
3816 MockRead("Set-Cookie: foo=bar\r\n"),
3817 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3818 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233819 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:243820 };
3821
Ryan Sleevib8d7ea02018-05-07 20:01:013822 StaticSocketDataProvider data(data_reads, data_writes);
ttuttle7933c112015-01-06 00:55:243823 session_deps_.socket_factory->AddSocketDataProvider(&data);
3824
3825 TestCompletionCallback callback;
3826
tfarina42834112016-09-22 13:38:203827 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013828 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:243829
3830 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013831 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:243832
bnc691fda62016-08-12 00:43:163833 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243834 ASSERT_TRUE(response);
3835 ASSERT_TRUE(response->headers);
3836 EXPECT_TRUE(response->headers->IsKeepAlive());
3837 EXPECT_EQ(407, response->headers->response_code());
3838 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3839 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
3840 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
3841
3842 std::string response_data;
bnc691fda62016-08-12 00:43:163843 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:013844 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:243845
3846 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
3847 session->CloseAllConnections();
3848}
3849
[email protected]8fdbcd22010-05-05 02:54:523850// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
3851// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:013852TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:523853 HttpRequestInfo request;
3854 request.method = "GET";
bncce36dca22015-04-21 22:11:233855 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103856 request.traffic_annotation =
3857 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:523858
[email protected]cb9bf6ca2011-01-28 13:15:273859 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:093860 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:163861 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:273862
[email protected]8fdbcd22010-05-05 02:54:523863 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233864 MockWrite(
3865 "GET / HTTP/1.1\r\n"
3866 "Host: www.example.org\r\n"
3867 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:523868 };
3869
3870 MockRead data_reads1[] = {
3871 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
3872 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3873 // Large content-length -- won't matter, as connection will be reset.
3874 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063875 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:523876 };
3877
Ryan Sleevib8d7ea02018-05-07 20:01:013878 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073879 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:523880
[email protected]49639fa2011-12-20 23:22:413881 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:523882
tfarina42834112016-09-22 13:38:203883 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013884 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:523885
3886 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:013887 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:523888}
3889
[email protected]7a67a8152010-11-05 18:31:103890// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
3891// through a non-authenticating proxy. The request should fail with
3892// ERR_UNEXPECTED_PROXY_AUTH.
3893// Note that it is impossible to detect if an HTTP server returns a 407 through
3894// a non-authenticating proxy - there is nothing to indicate whether the
3895// response came from the proxy or the server, so it is treated as if the proxy
3896// issued the challenge.
bncd16676a2016-07-20 16:23:013897TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:273898 HttpRequestInfo request;
3899 request.method = "GET";
bncce36dca22015-04-21 22:11:233900 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103901 request.traffic_annotation =
3902 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273903
Ramin Halavatica8d5252018-03-12 05:33:493904 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3905 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513906 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073907 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093908 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:103909
[email protected]7a67a8152010-11-05 18:31:103910 // Since we have proxy, should try to establish tunnel.
3911 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:173912 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3913 "Host: www.example.org:443\r\n"
3914 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103915
rsleevidb16bb02015-11-12 23:47:173916 MockWrite("GET / HTTP/1.1\r\n"
3917 "Host: www.example.org\r\n"
3918 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:103919 };
3920
3921 MockRead data_reads1[] = {
3922 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3923
3924 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
3925 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3926 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:063927 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:103928 };
3929
Ryan Sleevib8d7ea02018-05-07 20:01:013930 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073931 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:063932 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073933 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:103934
[email protected]49639fa2011-12-20 23:22:413935 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:103936
bnc691fda62016-08-12 00:43:163937 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:103938
bnc691fda62016-08-12 00:43:163939 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:103941
3942 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013943 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:463944 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403945 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:103946 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003947 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3948 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103949 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403950 entries, pos,
mikecirone8b85c432016-09-08 19:11:003951 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3952 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:103953}
[email protected]2df19bb2010-08-25 20:13:463954
mmenke2a1781d2015-10-07 19:25:333955// Test a proxy auth scheme that allows default credentials and a proxy server
3956// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:013957TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:333958 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
3959 HttpRequestInfo request;
3960 request.method = "GET";
3961 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:103962 request.traffic_annotation =
3963 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:333964
3965 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593966 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493967 ProxyResolutionService::CreateFixedFromPacResult(
3968 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:333969
Jeremy Roman0579ed62017-08-29 15:56:193970 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:333971 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:193972 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:333973 mock_handler->set_allows_default_credentials(true);
3974 auth_handler_factory->AddMockHandler(mock_handler.release(),
3975 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:483976 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:333977
3978 // Add NetLog just so can verify load timing information gets a NetLog ID.
3979 NetLog net_log;
3980 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:093981 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:333982
3983 // Since we have proxy, should try to establish tunnel.
3984 MockWrite data_writes1[] = {
3985 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173986 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:333987 "Proxy-Connection: keep-alive\r\n\r\n"),
3988 };
3989
3990 // The proxy responds to the connect with a 407, using a non-persistent
3991 // connection.
3992 MockRead data_reads1[] = {
3993 // No credentials.
3994 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3995 MockRead("Proxy-Authenticate: Mock\r\n"),
3996 MockRead("Proxy-Connection: close\r\n\r\n"),
3997 };
3998
3999 // Since the first connection couldn't be reused, need to establish another
4000 // once given credentials.
4001 MockWrite data_writes2[] = {
4002 // After calling trans->RestartWithAuth(), this is the request we should
4003 // be issuing -- the final header line contains the credentials.
4004 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174005 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334006 "Proxy-Connection: keep-alive\r\n"
4007 "Proxy-Authorization: auth_token\r\n\r\n"),
4008
4009 MockWrite("GET / HTTP/1.1\r\n"
4010 "Host: www.example.org\r\n"
4011 "Connection: keep-alive\r\n\r\n"),
4012 };
4013
4014 MockRead data_reads2[] = {
4015 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4016
4017 MockRead("HTTP/1.1 200 OK\r\n"),
4018 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4019 MockRead("Content-Length: 5\r\n\r\n"),
4020 MockRead(SYNCHRONOUS, "hello"),
4021 };
4022
Ryan Sleevib8d7ea02018-05-07 20:01:014023 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334024 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014025 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334026 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4027 SSLSocketDataProvider ssl(ASYNC, OK);
4028 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4029
bnc87dcefc2017-05-25 12:47:584030 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194031 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334032
4033 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204034 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014035 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334036
4037 const HttpResponseInfo* response = trans->GetResponseInfo();
4038 ASSERT_TRUE(response);
4039 ASSERT_TRUE(response->headers);
4040 EXPECT_FALSE(response->headers->IsKeepAlive());
4041 EXPECT_EQ(407, response->headers->response_code());
4042 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4043 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
wezca1070932016-05-26 20:30:524044 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334045
4046 LoadTimingInfo load_timing_info;
4047 // CONNECT requests and responses are handled at the connect job level, so
4048 // the transaction does not yet have a connection.
4049 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4050
4051 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014052 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334053 response = trans->GetResponseInfo();
4054 ASSERT_TRUE(response);
4055 ASSERT_TRUE(response->headers);
4056 EXPECT_TRUE(response->headers->IsKeepAlive());
4057 EXPECT_EQ(200, response->headers->response_code());
4058 EXPECT_EQ(5, response->headers->GetContentLength());
4059 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4060
4061 // The password prompt info should not be set.
4062 EXPECT_FALSE(response->auth_challenge);
4063
4064 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4065 TestLoadTimingNotReusedWithPac(load_timing_info,
4066 CONNECT_TIMING_HAS_SSL_TIMES);
4067
4068 trans.reset();
4069 session->CloseAllConnections();
4070}
4071
4072// Test a proxy auth scheme that allows default credentials and a proxy server
4073// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014074TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334075 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4076 HttpRequestInfo request;
4077 request.method = "GET";
4078 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104079 request.traffic_annotation =
4080 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334081
4082 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594083 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494084 ProxyResolutionService::CreateFixedFromPacResult(
4085 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334086
Jeremy Roman0579ed62017-08-29 15:56:194087 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334088 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194089 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334090 mock_handler->set_allows_default_credentials(true);
4091 auth_handler_factory->AddMockHandler(mock_handler.release(),
4092 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484093 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334094
4095 // Add NetLog just so can verify load timing information gets a NetLog ID.
4096 NetLog net_log;
4097 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094098 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334099
4100 // Should try to establish tunnel.
4101 MockWrite data_writes1[] = {
4102 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174103 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334104 "Proxy-Connection: keep-alive\r\n\r\n"),
4105
4106 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174107 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334108 "Proxy-Connection: keep-alive\r\n"
4109 "Proxy-Authorization: auth_token\r\n\r\n"),
4110 };
4111
4112 // The proxy responds to the connect with a 407, using a non-persistent
4113 // connection.
4114 MockRead data_reads1[] = {
4115 // No credentials.
4116 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4117 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4118 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4119 };
4120
4121 // Since the first connection was closed, need to establish another once given
4122 // credentials.
4123 MockWrite data_writes2[] = {
4124 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174125 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334126 "Proxy-Connection: keep-alive\r\n"
4127 "Proxy-Authorization: auth_token\r\n\r\n"),
4128
4129 MockWrite("GET / HTTP/1.1\r\n"
4130 "Host: www.example.org\r\n"
4131 "Connection: keep-alive\r\n\r\n"),
4132 };
4133
4134 MockRead data_reads2[] = {
4135 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4136
4137 MockRead("HTTP/1.1 200 OK\r\n"),
4138 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4139 MockRead("Content-Length: 5\r\n\r\n"),
4140 MockRead(SYNCHRONOUS, "hello"),
4141 };
4142
Ryan Sleevib8d7ea02018-05-07 20:01:014143 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334144 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014145 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334146 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4147 SSLSocketDataProvider ssl(ASYNC, OK);
4148 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4149
bnc87dcefc2017-05-25 12:47:584150 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194151 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334152
4153 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204154 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014155 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334156
4157 const HttpResponseInfo* response = trans->GetResponseInfo();
4158 ASSERT_TRUE(response);
4159 ASSERT_TRUE(response->headers);
4160 EXPECT_TRUE(response->headers->IsKeepAlive());
4161 EXPECT_EQ(407, response->headers->response_code());
4162 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4163 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4164 EXPECT_FALSE(response->auth_challenge);
4165
4166 LoadTimingInfo load_timing_info;
4167 // CONNECT requests and responses are handled at the connect job level, so
4168 // the transaction does not yet have a connection.
4169 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4170
4171 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014172 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334173
4174 response = trans->GetResponseInfo();
4175 ASSERT_TRUE(response);
4176 ASSERT_TRUE(response->headers);
4177 EXPECT_TRUE(response->headers->IsKeepAlive());
4178 EXPECT_EQ(200, response->headers->response_code());
4179 EXPECT_EQ(5, response->headers->GetContentLength());
4180 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4181
4182 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:524183 EXPECT_FALSE(response->auth_challenge);
mmenke2a1781d2015-10-07 19:25:334184
4185 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4186 TestLoadTimingNotReusedWithPac(load_timing_info,
4187 CONNECT_TIMING_HAS_SSL_TIMES);
4188
4189 trans.reset();
4190 session->CloseAllConnections();
4191}
4192
4193// Test a proxy auth scheme that allows default credentials and a proxy server
4194// that hangs up when credentials are initially sent, and hangs up again when
4195// they are retried.
bncd16676a2016-07-20 16:23:014196TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334197 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4198 HttpRequestInfo request;
4199 request.method = "GET";
4200 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104201 request.traffic_annotation =
4202 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334203
4204 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594205 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494206 ProxyResolutionService::CreateFixedFromPacResult(
4207 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334208
Jeremy Roman0579ed62017-08-29 15:56:194209 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334210 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194211 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334212 mock_handler->set_allows_default_credentials(true);
4213 auth_handler_factory->AddMockHandler(mock_handler.release(),
4214 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484215 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334216
4217 // Add NetLog just so can verify load timing information gets a NetLog ID.
4218 NetLog net_log;
4219 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094220 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334221
4222 // Should try to establish tunnel.
4223 MockWrite data_writes1[] = {
4224 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174225 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334226 "Proxy-Connection: keep-alive\r\n\r\n"),
4227
4228 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174229 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334230 "Proxy-Connection: keep-alive\r\n"
4231 "Proxy-Authorization: auth_token\r\n\r\n"),
4232 };
4233
4234 // The proxy responds to the connect with a 407, and then hangs up after the
4235 // second request is sent.
4236 MockRead data_reads1[] = {
4237 // No credentials.
4238 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4239 MockRead("Content-Length: 0\r\n"),
4240 MockRead("Proxy-Connection: keep-alive\r\n"),
4241 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4242 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4243 };
4244
4245 // HttpNetworkTransaction sees a reused connection that was closed with
4246 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4247 // request.
4248 MockWrite data_writes2[] = {
4249 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174250 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334251 "Proxy-Connection: keep-alive\r\n\r\n"),
4252 };
4253
4254 // The proxy, having had more than enough of us, just hangs up.
4255 MockRead data_reads2[] = {
4256 // No credentials.
4257 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4258 };
4259
Ryan Sleevib8d7ea02018-05-07 20:01:014260 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334261 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014262 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334263 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4264
bnc87dcefc2017-05-25 12:47:584265 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194266 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334267
4268 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204269 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014270 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334271
4272 const HttpResponseInfo* response = trans->GetResponseInfo();
4273 ASSERT_TRUE(response);
4274 ASSERT_TRUE(response->headers);
4275 EXPECT_TRUE(response->headers->IsKeepAlive());
4276 EXPECT_EQ(407, response->headers->response_code());
4277 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4278 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4279 EXPECT_FALSE(response->auth_challenge);
4280
4281 LoadTimingInfo load_timing_info;
4282 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4283
4284 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014285 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334286
4287 trans.reset();
4288 session->CloseAllConnections();
4289}
4290
4291// Test a proxy auth scheme that allows default credentials and a proxy server
4292// that hangs up when credentials are initially sent, and sends a challenge
4293// again they are retried.
bncd16676a2016-07-20 16:23:014294TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334295 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4296 HttpRequestInfo request;
4297 request.method = "GET";
4298 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104299 request.traffic_annotation =
4300 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334301
4302 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594303 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494304 ProxyResolutionService::CreateFixedFromPacResult(
4305 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334306
Jeremy Roman0579ed62017-08-29 15:56:194307 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334308 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194309 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334310 mock_handler->set_allows_default_credentials(true);
4311 auth_handler_factory->AddMockHandler(mock_handler.release(),
4312 HttpAuth::AUTH_PROXY);
4313 // Add another handler for the second challenge. It supports default
4314 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194315 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334316 mock_handler->set_allows_default_credentials(true);
4317 auth_handler_factory->AddMockHandler(mock_handler.release(),
4318 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484319 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334320
4321 // Add NetLog just so can verify load timing information gets a NetLog ID.
4322 NetLog net_log;
4323 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094324 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334325
4326 // Should try to establish tunnel.
4327 MockWrite data_writes1[] = {
4328 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174329 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334330 "Proxy-Connection: keep-alive\r\n\r\n"),
4331 };
4332
4333 // The proxy responds to the connect with a 407, using a non-persistent
4334 // connection.
4335 MockRead data_reads1[] = {
4336 // No credentials.
4337 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4338 MockRead("Proxy-Authenticate: Mock\r\n"),
4339 MockRead("Proxy-Connection: close\r\n\r\n"),
4340 };
4341
4342 // Since the first connection was closed, need to establish another once given
4343 // credentials.
4344 MockWrite data_writes2[] = {
4345 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174346 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334347 "Proxy-Connection: keep-alive\r\n"
4348 "Proxy-Authorization: auth_token\r\n\r\n"),
4349 };
4350
4351 MockRead data_reads2[] = {
4352 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4353 MockRead("Proxy-Authenticate: Mock\r\n"),
4354 MockRead("Proxy-Connection: close\r\n\r\n"),
4355 };
4356
Ryan Sleevib8d7ea02018-05-07 20:01:014357 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334358 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014359 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334360 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4361 SSLSocketDataProvider ssl(ASYNC, OK);
4362 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4363
bnc87dcefc2017-05-25 12:47:584364 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194365 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334366
4367 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204368 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014369 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334370
4371 const HttpResponseInfo* response = trans->GetResponseInfo();
4372 ASSERT_TRUE(response);
4373 ASSERT_TRUE(response->headers);
4374 EXPECT_EQ(407, response->headers->response_code());
4375 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4376 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4377 EXPECT_FALSE(response->auth_challenge);
4378
4379 LoadTimingInfo load_timing_info;
4380 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4381
4382 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014383 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334384 response = trans->GetResponseInfo();
4385 ASSERT_TRUE(response);
4386 ASSERT_TRUE(response->headers);
4387 EXPECT_EQ(407, response->headers->response_code());
4388 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4389 EXPECT_TRUE(response->auth_challenge);
4390
4391 trans.reset();
4392 session->CloseAllConnections();
4393}
4394
asankae2257db2016-10-11 22:03:164395// A more nuanced test than GenerateAuthToken test which asserts that
4396// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4397// unnecessarily invalidated, and that if the server co-operates, the
4398// authentication handshake can continue with the same scheme but with a
4399// different identity.
4400TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4401 HttpRequestInfo request;
4402 request.method = "GET";
4403 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104404 request.traffic_annotation =
4405 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164406
Jeremy Roman0579ed62017-08-29 15:56:194407 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164408 auth_handler_factory->set_do_init_from_challenge(true);
4409
4410 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194411 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164412 mock_handler->set_allows_default_credentials(true);
4413 mock_handler->set_allows_explicit_credentials(true);
4414 mock_handler->set_connection_based(true);
4415 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4416 auth_handler_factory->AddMockHandler(mock_handler.release(),
4417 HttpAuth::AUTH_SERVER);
4418
4419 // Add another handler for the second challenge. It supports default
4420 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194421 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164422 mock_handler->set_allows_default_credentials(true);
4423 mock_handler->set_allows_explicit_credentials(true);
4424 mock_handler->set_connection_based(true);
4425 auth_handler_factory->AddMockHandler(mock_handler.release(),
4426 HttpAuth::AUTH_SERVER);
4427 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4428
4429 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4430
4431 MockWrite data_writes1[] = {
4432 MockWrite("GET / HTTP/1.1\r\n"
4433 "Host: www.example.org\r\n"
4434 "Connection: keep-alive\r\n\r\n"),
4435 };
4436
4437 MockRead data_reads1[] = {
4438 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4439 "WWW-Authenticate: Mock\r\n"
4440 "Connection: keep-alive\r\n\r\n"),
4441 };
4442
4443 // Identical to data_writes1[]. The AuthHandler encounters a
4444 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4445 // transaction procceds without an authorization header.
4446 MockWrite data_writes2[] = {
4447 MockWrite("GET / HTTP/1.1\r\n"
4448 "Host: www.example.org\r\n"
4449 "Connection: keep-alive\r\n\r\n"),
4450 };
4451
4452 MockRead data_reads2[] = {
4453 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4454 "WWW-Authenticate: Mock\r\n"
4455 "Connection: keep-alive\r\n\r\n"),
4456 };
4457
4458 MockWrite data_writes3[] = {
4459 MockWrite("GET / HTTP/1.1\r\n"
4460 "Host: www.example.org\r\n"
4461 "Connection: keep-alive\r\n"
4462 "Authorization: auth_token\r\n\r\n"),
4463 };
4464
4465 MockRead data_reads3[] = {
4466 MockRead("HTTP/1.1 200 OK\r\n"
4467 "Content-Length: 5\r\n"
4468 "Content-Type: text/plain\r\n"
4469 "Connection: keep-alive\r\n\r\n"
4470 "Hello"),
4471 };
4472
Ryan Sleevib8d7ea02018-05-07 20:01:014473 StaticSocketDataProvider data1(data_reads1, data_writes1);
asankae2257db2016-10-11 22:03:164474 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4475
Ryan Sleevib8d7ea02018-05-07 20:01:014476 StaticSocketDataProvider data2(data_reads2, data_writes2);
asankae2257db2016-10-11 22:03:164477 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4478
Ryan Sleevib8d7ea02018-05-07 20:01:014479 StaticSocketDataProvider data3(data_reads3, data_writes3);
asankae2257db2016-10-11 22:03:164480 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4481
bnc87dcefc2017-05-25 12:47:584482 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194483 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164484
4485 TestCompletionCallback callback;
4486 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4487 EXPECT_THAT(callback.GetResult(rv), IsOk());
4488
4489 const HttpResponseInfo* response = trans->GetResponseInfo();
4490 ASSERT_TRUE(response);
4491 ASSERT_TRUE(response->headers);
4492 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4493
4494 // The following three tests assert that an authentication challenge was
4495 // received and that the stack is ready to respond to the challenge using
4496 // ambient credentials.
4497 EXPECT_EQ(401, response->headers->response_code());
4498 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
4499 EXPECT_FALSE(response->auth_challenge);
4500
4501 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4502 EXPECT_THAT(callback.GetResult(rv), IsOk());
4503 response = trans->GetResponseInfo();
4504 ASSERT_TRUE(response);
4505 ASSERT_TRUE(response->headers);
4506
4507 // The following three tests assert that an authentication challenge was
4508 // received and that the stack needs explicit credentials before it is ready
4509 // to respond to the challenge.
4510 EXPECT_EQ(401, response->headers->response_code());
4511 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
4512 EXPECT_TRUE(response->auth_challenge);
4513
4514 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4515 EXPECT_THAT(callback.GetResult(rv), IsOk());
4516 response = trans->GetResponseInfo();
4517 ASSERT_TRUE(response);
4518 ASSERT_TRUE(response->headers);
4519 EXPECT_EQ(200, response->headers->response_code());
4520
4521 trans.reset();
4522 session->CloseAllConnections();
4523}
4524
Matt Menked1eb6d42018-01-17 04:54:064525// Proxy resolver that returns a proxy with the same host and port for different
4526// schemes, based on the path of the URL being requests.
4527class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4528 public:
4529 SameProxyWithDifferentSchemesProxyResolver() {}
4530 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4531
4532 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4533
4534 static HostPortPair ProxyHostPortPair() {
4535 return HostPortPair::FromString(ProxyHostPortPairAsString());
4536 }
4537
4538 // ProxyResolver implementation.
4539 int GetProxyForURL(const GURL& url,
4540 ProxyInfo* results,
Bence Békycc5b88a2018-05-25 20:24:174541 CompletionOnceCallback callback,
Matt Menked1eb6d42018-01-17 04:54:064542 std::unique_ptr<Request>* request,
4543 const NetLogWithSource& /*net_log*/) override {
4544 *results = ProxyInfo();
Ramin Halavati921731ea2018-03-16 08:24:574545 results->set_traffic_annotation(
4546 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
Matt Menked1eb6d42018-01-17 04:54:064547 if (url.path() == "/socks4") {
4548 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4549 return OK;
4550 }
4551 if (url.path() == "/socks5") {
4552 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4553 return OK;
4554 }
4555 if (url.path() == "/http") {
4556 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4557 return OK;
4558 }
4559 if (url.path() == "/https") {
4560 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4561 return OK;
4562 }
4563 NOTREACHED();
4564 return ERR_NOT_IMPLEMENTED;
4565 }
4566
4567 private:
4568 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4569};
4570
4571class SameProxyWithDifferentSchemesProxyResolverFactory
4572 : public ProxyResolverFactory {
4573 public:
4574 SameProxyWithDifferentSchemesProxyResolverFactory()
4575 : ProxyResolverFactory(false) {}
4576
Lily Houghton99597862018-03-07 16:40:424577 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
4578 std::unique_ptr<ProxyResolver>* resolver,
Bence Békycc5b88a2018-05-25 20:24:174579 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:424580 std::unique_ptr<Request>* request) override {
Matt Menked1eb6d42018-01-17 04:54:064581 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4582 return OK;
4583 }
4584
4585 private:
4586 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4587};
4588
4589// Check that when different proxy schemes are all applied to a proxy at the
4590// same address, the sonnections are not grouped together. i.e., a request to
4591// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4592// request to foo.com using proxy.com as an HTTP proxy.
4593TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Ramin Halavatica8d5252018-03-12 05:33:494594 session_deps_.proxy_resolution_service =
4595 std::make_unique<ProxyResolutionService>(
4596 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
4597 ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
4598 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4599 nullptr);
Matt Menked1eb6d42018-01-17 04:54:064600
4601 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4602
4603 MockWrite socks_writes[] = {
4604 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4605 kSOCKS4OkRequestLocalHostPort80Length),
4606 MockWrite(SYNCHRONOUS,
4607 "GET /socks4 HTTP/1.1\r\n"
4608 "Host: test\r\n"
4609 "Connection: keep-alive\r\n\r\n"),
4610 };
4611 MockRead socks_reads[] = {
4612 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4613 MockRead("HTTP/1.0 200 OK\r\n"
4614 "Connection: keep-alive\r\n"
4615 "Content-Length: 15\r\n\r\n"
4616 "SOCKS4 Response"),
4617 };
Ryan Sleevib8d7ea02018-05-07 20:01:014618 StaticSocketDataProvider socks_data(socks_reads, socks_writes);
Matt Menked1eb6d42018-01-17 04:54:064619 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4620
4621 const char kSOCKS5Request[] = {
4622 0x05, // Version
4623 0x01, // Command (CONNECT)
4624 0x00, // Reserved
4625 0x03, // Address type (DOMAINNAME)
4626 0x04, // Length of domain (4)
4627 't', 'e', 's', 't', // Domain string
4628 0x00, 0x50, // 16-bit port (80)
4629 };
4630 MockWrite socks5_writes[] = {
4631 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
4632 MockWrite(ASYNC, kSOCKS5Request, arraysize(kSOCKS5Request)),
4633 MockWrite(SYNCHRONOUS,
4634 "GET /socks5 HTTP/1.1\r\n"
4635 "Host: test\r\n"
4636 "Connection: keep-alive\r\n\r\n"),
4637 };
4638 MockRead socks5_reads[] = {
4639 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
4640 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
4641 MockRead("HTTP/1.0 200 OK\r\n"
4642 "Connection: keep-alive\r\n"
4643 "Content-Length: 15\r\n\r\n"
4644 "SOCKS5 Response"),
4645 };
Ryan Sleevib8d7ea02018-05-07 20:01:014646 StaticSocketDataProvider socks5_data(socks5_reads, socks5_writes);
Matt Menked1eb6d42018-01-17 04:54:064647 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
4648
4649 MockWrite http_writes[] = {
4650 MockWrite(SYNCHRONOUS,
4651 "GET http://test/http HTTP/1.1\r\n"
4652 "Host: test\r\n"
4653 "Proxy-Connection: keep-alive\r\n\r\n"),
4654 };
4655 MockRead http_reads[] = {
4656 MockRead("HTTP/1.1 200 OK\r\n"
4657 "Proxy-Connection: keep-alive\r\n"
4658 "Content-Length: 13\r\n\r\n"
4659 "HTTP Response"),
4660 };
Ryan Sleevib8d7ea02018-05-07 20:01:014661 StaticSocketDataProvider http_data(http_reads, http_writes);
Matt Menked1eb6d42018-01-17 04:54:064662 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
4663
4664 MockWrite https_writes[] = {
4665 MockWrite(SYNCHRONOUS,
4666 "GET http://test/https HTTP/1.1\r\n"
4667 "Host: test\r\n"
4668 "Proxy-Connection: keep-alive\r\n\r\n"),
4669 };
4670 MockRead https_reads[] = {
4671 MockRead("HTTP/1.1 200 OK\r\n"
4672 "Proxy-Connection: keep-alive\r\n"
4673 "Content-Length: 14\r\n\r\n"
4674 "HTTPS Response"),
4675 };
Ryan Sleevib8d7ea02018-05-07 20:01:014676 StaticSocketDataProvider https_data(https_reads, https_writes);
Matt Menked1eb6d42018-01-17 04:54:064677 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
4678 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
4679 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4680
4681 struct TestCase {
4682 GURL url;
4683 std::string expected_response;
4684 // How many idle sockets there should be in the SOCKS proxy socket pool
4685 // after the test.
4686 int expected_idle_socks_sockets;
4687 // How many idle sockets there should be in the HTTP proxy socket pool after
4688 // the test.
4689 int expected_idle_http_sockets;
4690 } const kTestCases[] = {
4691 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0},
4692 {GURL("http://test/socks5"), "SOCKS5 Response", 2, 0},
4693 {GURL("http://test/http"), "HTTP Response", 2, 1},
4694 {GURL("http://test/https"), "HTTPS Response", 2, 2},
4695 };
4696
4697 for (const auto& test_case : kTestCases) {
4698 HttpRequestInfo request;
4699 request.method = "GET";
4700 request.url = test_case.url;
Ramin Halavatib5e433e2018-02-07 07:41:104701 request.traffic_annotation =
4702 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:064703 std::unique_ptr<HttpNetworkTransaction> trans =
4704 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
4705 session.get());
4706 TestCompletionCallback callback;
4707 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4708 EXPECT_THAT(callback.GetResult(rv), IsOk());
4709
4710 const HttpResponseInfo* response = trans->GetResponseInfo();
4711 ASSERT_TRUE(response);
4712 ASSERT_TRUE(response->headers);
4713 EXPECT_EQ(200, response->headers->response_code());
4714 std::string response_data;
4715 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
4716 EXPECT_EQ(test_case.expected_response, response_data);
4717
4718 // Return the socket to the socket pool, so can make sure it's not used for
4719 // the next requests.
4720 trans.reset();
4721 base::RunLoop().RunUntilIdle();
4722
4723 // Check the number of idle sockets in the pool, to make sure that used
4724 // sockets are indeed being returned to the socket pool. If each request
4725 // doesn't return an idle socket to the pool, the test would incorrectly
4726 // pass.
4727 EXPECT_EQ(
4728 test_case.expected_idle_socks_sockets,
4729 session
4730 ->GetSocketPoolForSOCKSProxy(
4731 HttpNetworkSession::NORMAL_SOCKET_POOL,
4732 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4733 ->IdleSocketCount());
4734 EXPECT_EQ(
4735 test_case.expected_idle_http_sockets,
4736 session
4737 ->GetSocketPoolForHTTPProxy(
4738 HttpNetworkSession::NORMAL_SOCKET_POOL,
4739 SameProxyWithDifferentSchemesProxyResolver::ProxyHostPortPair())
4740 ->IdleSocketCount());
4741 }
4742}
4743
[email protected]029c83b62013-01-24 05:28:204744// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:014745TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204746 HttpRequestInfo request1;
4747 request1.method = "GET";
bncce36dca22015-04-21 22:11:234748 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:104749 request1.traffic_annotation =
4750 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204751
4752 HttpRequestInfo request2;
4753 request2.method = "GET";
bncce36dca22015-04-21 22:11:234754 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:104755 request2.traffic_annotation =
4756 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204757
4758 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494759 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4760 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514761 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074762 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094763 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204764
4765 // Since we have proxy, should try to establish tunnel.
4766 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174767 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4768 "Host: www.example.org:443\r\n"
4769 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204770
rsleevidb16bb02015-11-12 23:47:174771 MockWrite("GET /1 HTTP/1.1\r\n"
4772 "Host: www.example.org\r\n"
4773 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204774
rsleevidb16bb02015-11-12 23:47:174775 MockWrite("GET /2 HTTP/1.1\r\n"
4776 "Host: www.example.org\r\n"
4777 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204778 };
4779
4780 // The proxy responds to the connect with a 407, using a persistent
4781 // connection.
4782 MockRead data_reads1[] = {
4783 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4784
4785 MockRead("HTTP/1.1 200 OK\r\n"),
4786 MockRead("Content-Length: 1\r\n\r\n"),
4787 MockRead(SYNCHRONOUS, "1"),
4788
4789 MockRead("HTTP/1.1 200 OK\r\n"),
4790 MockRead("Content-Length: 2\r\n\r\n"),
4791 MockRead(SYNCHRONOUS, "22"),
4792 };
4793
Ryan Sleevib8d7ea02018-05-07 20:01:014794 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074795 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204796 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074797 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204798
4799 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584800 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194801 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204802
4803 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014804 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204805
4806 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014807 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204808
4809 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524810 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:474811 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:524812 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204813 EXPECT_EQ(1, response1->headers->GetContentLength());
4814
4815 LoadTimingInfo load_timing_info1;
4816 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4817 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
4818
4819 trans1.reset();
4820
4821 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584822 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194823 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204824
4825 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014826 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204827
4828 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014829 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204830
4831 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524832 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:474833 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:524834 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204835 EXPECT_EQ(2, response2->headers->GetContentLength());
4836
4837 LoadTimingInfo load_timing_info2;
4838 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4839 TestLoadTimingReused(load_timing_info2);
4840
4841 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4842
4843 trans2.reset();
4844 session->CloseAllConnections();
4845}
4846
4847// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:014848TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:204849 HttpRequestInfo request1;
4850 request1.method = "GET";
bncce36dca22015-04-21 22:11:234851 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e2018-02-07 07:41:104852 request1.traffic_annotation =
4853 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204854
4855 HttpRequestInfo request2;
4856 request2.method = "GET";
bncce36dca22015-04-21 22:11:234857 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e2018-02-07 07:41:104858 request2.traffic_annotation =
4859 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:204860
4861 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594862 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494863 ProxyResolutionService::CreateFixedFromPacResult(
4864 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514865 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074866 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094867 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:204868
4869 // Since we have proxy, should try to establish tunnel.
4870 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174871 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4872 "Host: www.example.org:443\r\n"
4873 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204874
rsleevidb16bb02015-11-12 23:47:174875 MockWrite("GET /1 HTTP/1.1\r\n"
4876 "Host: www.example.org\r\n"
4877 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204878
rsleevidb16bb02015-11-12 23:47:174879 MockWrite("GET /2 HTTP/1.1\r\n"
4880 "Host: www.example.org\r\n"
4881 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:204882 };
4883
4884 // The proxy responds to the connect with a 407, using a persistent
4885 // connection.
4886 MockRead data_reads1[] = {
4887 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4888
4889 MockRead("HTTP/1.1 200 OK\r\n"),
4890 MockRead("Content-Length: 1\r\n\r\n"),
4891 MockRead(SYNCHRONOUS, "1"),
4892
4893 MockRead("HTTP/1.1 200 OK\r\n"),
4894 MockRead("Content-Length: 2\r\n\r\n"),
4895 MockRead(SYNCHRONOUS, "22"),
4896 };
4897
Ryan Sleevib8d7ea02018-05-07 20:01:014898 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074899 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:204900 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074901 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:204902
4903 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:584904 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:194905 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204906
4907 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014908 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204909
4910 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014911 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204912
4913 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:524914 ASSERT_TRUE(response1);
4915 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:204916 EXPECT_EQ(1, response1->headers->GetContentLength());
4917
4918 LoadTimingInfo load_timing_info1;
4919 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
4920 TestLoadTimingNotReusedWithPac(load_timing_info1,
4921 CONNECT_TIMING_HAS_SSL_TIMES);
4922
4923 trans1.reset();
4924
4925 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:584926 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:194927 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:204928
4929 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014930 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:204931
4932 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:014933 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:204934
4935 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:524936 ASSERT_TRUE(response2);
4937 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:204938 EXPECT_EQ(2, response2->headers->GetContentLength());
4939
4940 LoadTimingInfo load_timing_info2;
4941 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
4942 TestLoadTimingReusedWithPac(load_timing_info2);
4943
4944 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
4945
4946 trans2.reset();
4947 session->CloseAllConnections();
4948}
4949
[email protected]2df19bb2010-08-25 20:13:464950// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:014951TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:274952 HttpRequestInfo request;
4953 request.method = "GET";
bncce36dca22015-04-21 22:11:234954 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:104955 request.traffic_annotation =
4956 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:274957
[email protected]2df19bb2010-08-25 20:13:464958 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494959 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4960 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514961 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074962 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094963 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:464964
[email protected]2df19bb2010-08-25 20:13:464965 // Since we have proxy, should use full url
4966 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234967 MockWrite(
4968 "GET http://www.example.org/ HTTP/1.1\r\n"
4969 "Host: www.example.org\r\n"
4970 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:464971 };
4972
4973 MockRead data_reads1[] = {
4974 MockRead("HTTP/1.1 200 OK\r\n"),
4975 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4976 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064977 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:464978 };
4979
Ryan Sleevib8d7ea02018-05-07 20:01:014980 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074981 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064982 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074983 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:464984
[email protected]49639fa2011-12-20 23:22:414985 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:464986
bnc691fda62016-08-12 00:43:164987 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:504988
bnc691fda62016-08-12 00:43:164989 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014990 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:464991
4992 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014993 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:464994
[email protected]58e32bb2013-01-21 18:23:254995 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:164996 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:254997 TestLoadTimingNotReused(load_timing_info,
4998 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
4999
bnc691fda62016-08-12 00:43:165000 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525001 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465002
tbansal2ecbbc72016-10-06 17:15:475003 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:465004 EXPECT_TRUE(response->headers->IsKeepAlive());
5005 EXPECT_EQ(200, response->headers->response_code());
5006 EXPECT_EQ(100, response->headers->GetContentLength());
5007 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5008
5009 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525010 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465011}
5012
[email protected]7642b5ae2010-09-01 20:55:175013// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015014TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275015 HttpRequestInfo request;
5016 request.method = "GET";
bncce36dca22015-04-21 22:11:235017 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105018 request.traffic_annotation =
5019 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275020
[email protected]7642b5ae2010-09-01 20:55:175021 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495022 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5023 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515024 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075025 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095026 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175027
bncce36dca22015-04-21 22:11:235028 // fetch http://www.example.org/ via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135029 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455030 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415031 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175032
Ryan Hamilton0239aac2018-05-19 00:03:135033 spdy::SpdySerializedFrame resp(
5034 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
5035 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175036 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415037 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175038 };
5039
Ryan Sleevib8d7ea02018-05-07 20:01:015040 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075041 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175042
[email protected]8ddf8322012-02-23 18:08:065043 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365044 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075045 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175046
[email protected]49639fa2011-12-20 23:22:415047 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175048
bnc691fda62016-08-12 00:43:165049 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505050
bnc691fda62016-08-12 00:43:165051 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015052 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175053
5054 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015055 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175056
[email protected]58e32bb2013-01-21 18:23:255057 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165058 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255059 TestLoadTimingNotReused(load_timing_info,
5060 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5061
bnc691fda62016-08-12 00:43:165062 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525063 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475064 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525065 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025066 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175067
5068 std::string response_data;
bnc691fda62016-08-12 00:43:165069 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235070 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175071}
5072
[email protected]1c173852014-06-19 12:51:505073// Verifies that a session which races and wins against the owning transaction
5074// (completing prior to host resolution), doesn't fail the transaction.
5075// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015076TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505077 HttpRequestInfo request;
5078 request.method = "GET";
bncce36dca22015-04-21 22:11:235079 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105080 request.traffic_annotation =
5081 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505082
5083 // Configure SPDY proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495084 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5085 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515086 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505087 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095088 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505089
bncce36dca22015-04-21 22:11:235090 // Fetch http://www.example.org/ through the SPDY proxy.
Ryan Hamilton0239aac2018-05-19 00:03:135091 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455092 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415093 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505094
Ryan Hamilton0239aac2018-05-19 00:03:135095 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5096 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505097 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415098 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505099 };
5100
Ryan Sleevib8d7ea02018-05-07 20:01:015101 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]1c173852014-06-19 12:51:505102 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5103
5104 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365105 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505106 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5107
5108 TestCompletionCallback callback1;
5109
bnc691fda62016-08-12 00:43:165110 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505111
5112 // Stall the hostname resolution begun by the transaction.
[email protected]1c173852014-06-19 12:51:505113 session_deps_.host_resolver->set_ondemand_mode(true);
5114
bnc691fda62016-08-12 00:43:165115 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015116 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505117
5118 // Race a session to the proxy, which completes first.
5119 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045120 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
5121 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]1c173852014-06-19 12:51:505122 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525123 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505124
5125 // Unstall the resolution begun by the transaction.
5126 session_deps_.host_resolver->set_ondemand_mode(true);
5127 session_deps_.host_resolver->ResolveAllPending();
5128
5129 EXPECT_FALSE(callback1.have_result());
5130 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015131 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505132
bnc691fda62016-08-12 00:43:165133 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525134 ASSERT_TRUE(response);
5135 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025136 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505137
5138 std::string response_data;
bnc691fda62016-08-12 00:43:165139 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505140 EXPECT_EQ(kUploadData, response_data);
5141}
5142
[email protected]dc7bd1c52010-11-12 00:01:135143// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015144TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275145 HttpRequestInfo request;
5146 request.method = "GET";
bncce36dca22015-04-21 22:11:235147 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105148 request.traffic_annotation =
5149 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275150
[email protected]79cb5c12011-09-12 13:12:045151 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495152 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5153 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515154 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075155 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095156 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135157
[email protected]dc7bd1c52010-11-12 00:01:135158 // The first request will be a bare GET, the second request will be a
5159 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455160 spdy_util_.set_default_url(request.url);
Ryan Hamilton0239aac2018-05-19 00:03:135161 spdy::SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485162 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385163 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135164 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465165 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135166 };
Ryan Hamilton0239aac2018-05-19 00:03:135167 spdy::SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
bncdf80d44fd2016-07-15 20:27:415168 kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485169 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135170 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415171 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135172 };
5173
5174 // The first response is a 407 proxy authentication challenge, and the second
5175 // response will be a 200 response since the second request includes a valid
5176 // Authorization header.
5177 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465178 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135179 };
Ryan Hamilton0239aac2018-05-19 00:03:135180 spdy::SpdySerializedFrame resp_authentication(
5181 spdy_util_.ConstructSpdyReplyError(
5182 "407", kExtraAuthenticationHeaders,
5183 arraysize(kExtraAuthenticationHeaders) / 2, 1));
5184 spdy::SpdySerializedFrame body_authentication(
bncdf80d44fd2016-07-15 20:27:415185 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:135186 spdy::SpdySerializedFrame resp_data(
5187 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
5188 spdy::SpdySerializedFrame body_data(
5189 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135190 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415191 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465192 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415193 CreateMockRead(resp_data, 4),
5194 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135195 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135196 };
5197
Ryan Sleevib8d7ea02018-05-07 20:01:015198 SequencedSocketData data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075199 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135200
[email protected]8ddf8322012-02-23 18:08:065201 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365202 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075203 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135204
[email protected]49639fa2011-12-20 23:22:415205 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135206
bnc691fda62016-08-12 00:43:165207 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135208
bnc691fda62016-08-12 00:43:165209 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015210 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135211
5212 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015213 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135214
bnc691fda62016-08-12 00:43:165215 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135216
wezca1070932016-05-26 20:30:525217 ASSERT_TRUE(response);
5218 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135219 EXPECT_EQ(407, response->headers->response_code());
5220 EXPECT_TRUE(response->was_fetched_via_spdy);
asanka098c0092016-06-16 20:18:435221 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]dc7bd1c52010-11-12 00:01:135222
[email protected]49639fa2011-12-20 23:22:415223 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135224
bnc691fda62016-08-12 00:43:165225 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015226 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135227
5228 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015229 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135230
bnc691fda62016-08-12 00:43:165231 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135232
wezca1070932016-05-26 20:30:525233 ASSERT_TRUE(response_restart);
5234 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135235 EXPECT_EQ(200, response_restart->headers->response_code());
5236 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525237 EXPECT_FALSE(response_restart->auth_challenge);
[email protected]dc7bd1c52010-11-12 00:01:135238}
5239
[email protected]d9da5fe2010-10-13 22:37:165240// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015241TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275242 HttpRequestInfo request;
5243 request.method = "GET";
bncce36dca22015-04-21 22:11:235244 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105245 request.traffic_annotation =
5246 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275247
[email protected]d9da5fe2010-10-13 22:37:165248 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495249 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5250 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515251 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075252 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095253 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165254
bnc691fda62016-08-12 00:43:165255 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165256
bncce36dca22015-04-21 22:11:235257 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135258 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235259 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5260 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165261
bncce36dca22015-04-21 22:11:235262 const char get[] =
5263 "GET / HTTP/1.1\r\n"
5264 "Host: www.example.org\r\n"
5265 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135266 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195267 spdy_util_.ConstructSpdyDataFrame(1, get, false));
Ryan Hamilton0239aac2018-05-19 00:03:135268 spdy::SpdySerializedFrame conn_resp(
5269 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165270 const char resp[] = "HTTP/1.1 200 OK\r\n"
5271 "Content-Length: 10\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135272 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195273 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:135274 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195275 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
Ryan Hamilton0239aac2018-05-19 00:03:135276 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:415277 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045278
5279 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415280 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5281 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045282 };
5283
[email protected]d9da5fe2010-10-13 22:37:165284 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415285 CreateMockRead(conn_resp, 1, ASYNC),
5286 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5287 CreateMockRead(wrapped_body, 4, ASYNC),
5288 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135289 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165290 };
5291
Ryan Sleevib8d7ea02018-05-07 20:01:015292 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075293 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165294
[email protected]8ddf8322012-02-23 18:08:065295 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365296 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075297 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065298 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075299 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165300
[email protected]49639fa2011-12-20 23:22:415301 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165302
bnc691fda62016-08-12 00:43:165303 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015304 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165305
5306 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015307 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165308
[email protected]58e32bb2013-01-21 18:23:255309 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165310 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255311 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5312
bnc691fda62016-08-12 00:43:165313 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525314 ASSERT_TRUE(response);
5315 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165316 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5317
5318 std::string response_data;
bnc691fda62016-08-12 00:43:165319 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165320 EXPECT_EQ("1234567890", response_data);
5321}
5322
5323// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015324TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5325 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385326
[email protected]cb9bf6ca2011-01-28 13:15:275327 HttpRequestInfo request;
5328 request.method = "GET";
bncce36dca22015-04-21 22:11:235329 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105330 request.traffic_annotation =
5331 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275332
[email protected]d9da5fe2010-10-13 22:37:165333 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495334 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5335 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515336 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075337 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095338 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165339
bnc691fda62016-08-12 00:43:165340 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165341
bncce36dca22015-04-21 22:11:235342 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135343 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235344 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
5345 // fetch https://www.example.org/ via SPDY
5346 const char kMyUrl[] = "https://www.example.org/";
Ryan Hamilton0239aac2018-05-19 00:03:135347 spdy::SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495348 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:135349 spdy::SpdySerializedFrame wrapped_get(
5350 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
5351 spdy::SpdySerializedFrame conn_resp(
5352 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5353 spdy::SpdySerializedFrame get_resp(
bnc42331402016-07-25 13:36:155354 spdy_util_wrapped.ConstructSpdyGetReply(NULL, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135355 spdy::SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025356 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135357 spdy::SpdySerializedFrame body(
5358 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5359 spdy::SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025360 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135361 spdy::SpdySerializedFrame window_update_get_resp(
bncdf80d44fd2016-07-15 20:27:415362 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
Ryan Hamilton0239aac2018-05-19 00:03:135363 spdy::SpdySerializedFrame window_update_body(
bncdf80d44fd2016-07-15 20:27:415364 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045365
5366 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415367 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5368 CreateMockWrite(window_update_get_resp, 6),
5369 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045370 };
5371
[email protected]d9da5fe2010-10-13 22:37:165372 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415373 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095374 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415375 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5376 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135377 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165378 };
5379
Ryan Sleevib8d7ea02018-05-07 20:01:015380 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075381 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165382
[email protected]8ddf8322012-02-23 18:08:065383 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365384 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075385 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065386 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365387 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075388 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165389
[email protected]49639fa2011-12-20 23:22:415390 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165391
bnc691fda62016-08-12 00:43:165392 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015393 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165394
rch32320842015-05-16 15:57:095395 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555396 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095397 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595398 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165399 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015400 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165401
[email protected]58e32bb2013-01-21 18:23:255402 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165403 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255404 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5405
bnc691fda62016-08-12 00:43:165406 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525407 ASSERT_TRUE(response);
5408 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025409 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165410
5411 std::string response_data;
bnc691fda62016-08-12 00:43:165412 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235413 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165414}
5415
5416// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015417TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275418 HttpRequestInfo request;
5419 request.method = "GET";
bncce36dca22015-04-21 22:11:235420 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105421 request.traffic_annotation =
5422 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275423
[email protected]d9da5fe2010-10-13 22:37:165424 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495425 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5426 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515427 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075428 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095429 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165430
bnc691fda62016-08-12 00:43:165431 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165432
bncce36dca22015-04-21 22:11:235433 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135434 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235435 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:135436 spdy::SpdySerializedFrame get(
5437 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165438
5439 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415440 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165441 };
5442
Ryan Hamilton0239aac2018-05-19 00:03:135443 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
5444 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165445 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415446 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165447 };
5448
Ryan Sleevib8d7ea02018-05-07 20:01:015449 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075450 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165451
[email protected]8ddf8322012-02-23 18:08:065452 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365453 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075454 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065455 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365456 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075457 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165458
[email protected]49639fa2011-12-20 23:22:415459 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165460
bnc691fda62016-08-12 00:43:165461 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015462 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165463
5464 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015465 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165466
ttuttle960fcbf2016-04-19 13:26:325467 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165468}
5469
[email protected]f6c63db52013-02-02 00:35:225470// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5471// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:015472TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225473 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
5474 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495475 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5476 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515477 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075478 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095479 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505480 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225481
5482 HttpRequestInfo request1;
5483 request1.method = "GET";
bncce36dca22015-04-21 22:11:235484 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225485 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105486 request1.traffic_annotation =
5487 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225488
5489 HttpRequestInfo request2;
5490 request2.method = "GET";
bncce36dca22015-04-21 22:11:235491 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225492 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105493 request2.traffic_annotation =
5494 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225495
bncce36dca22015-04-21 22:11:235496 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:135497 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235498 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:135499 spdy::SpdySerializedFrame conn_resp1(
5500 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225501
bncce36dca22015-04-21 22:11:235502 // Fetch https://www.example.org/ via HTTP.
5503 const char get1[] =
5504 "GET / HTTP/1.1\r\n"
5505 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225506 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135507 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:195508 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:225509 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5510 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135511 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:195512 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:135513 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:195514 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:135515 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:415516 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225517
bncce36dca22015-04-21 22:11:235518 // CONNECT to mail.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:135519 spdy::SpdyHeaderBlock connect2_block;
5520 connect2_block[spdy::kHttp2MethodHeader] = "CONNECT";
5521 connect2_block[spdy::kHttp2AuthorityHeader] = "mail.example.org:443";
5522 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
bnc42331402016-07-25 13:36:155523 3, std::move(connect2_block), LOWEST, false));
[email protected]601e03f12014-04-06 16:26:395524
Ryan Hamilton0239aac2018-05-19 00:03:135525 spdy::SpdySerializedFrame conn_resp2(
5526 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]f6c63db52013-02-02 00:35:225527
bncce36dca22015-04-21 22:11:235528 // Fetch https://mail.example.org/ via HTTP.
5529 const char get2[] =
5530 "GET / HTTP/1.1\r\n"
5531 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225532 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135533 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:195534 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:225535 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5536 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135537 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:195538 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:135539 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:195540 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:225541
5542 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415543 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5544 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:225545 };
5546
5547 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415548 CreateMockRead(conn_resp1, 1, ASYNC),
5549 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
5550 CreateMockRead(wrapped_body1, 4, ASYNC),
5551 CreateMockRead(conn_resp2, 6, ASYNC),
5552 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
5553 CreateMockRead(wrapped_body2, 9, ASYNC),
5554 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:225555 };
5556
Ryan Sleevib8d7ea02018-05-07 20:01:015557 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:505558 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225559
5560 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365561 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505562 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225563 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505564 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225565 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505566 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:225567
5568 TestCompletionCallback callback;
5569
bnc691fda62016-08-12 00:43:165570 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205571 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015572 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225573
5574 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165575 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:225576 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5577
bnc691fda62016-08-12 00:43:165578 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525579 ASSERT_TRUE(response);
5580 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225581 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5582
5583 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:445584 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
bnc691fda62016-08-12 00:43:165585 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505586 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225587
bnc691fda62016-08-12 00:43:165588 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205589 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015590 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225591
5592 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165593 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225594 // Even though the SPDY connection is reused, a new tunnelled connection has
5595 // to be created, so the socket's load timing looks like a fresh connection.
5596 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
5597
5598 // The requests should have different IDs, since they each are using their own
5599 // separate stream.
5600 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5601
bnc691fda62016-08-12 00:43:165602 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505603 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225604}
5605
5606// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
5607// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:015608TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:225609 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
5610 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495611 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5612 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515613 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075614 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095615 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505616 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225617
5618 HttpRequestInfo request1;
5619 request1.method = "GET";
bncce36dca22015-04-21 22:11:235620 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225621 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105622 request1.traffic_annotation =
5623 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225624
5625 HttpRequestInfo request2;
5626 request2.method = "GET";
bncce36dca22015-04-21 22:11:235627 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:225628 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105629 request2.traffic_annotation =
5630 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225631
bncce36dca22015-04-21 22:11:235632 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:135633 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:235634 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:135635 spdy::SpdySerializedFrame conn_resp1(
5636 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]f6c63db52013-02-02 00:35:225637
bncce36dca22015-04-21 22:11:235638 // Fetch https://www.example.org/ via HTTP.
5639 const char get1[] =
5640 "GET / HTTP/1.1\r\n"
5641 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225642 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135643 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:195644 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:225645 const char resp1[] = "HTTP/1.1 200 OK\r\n"
5646 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135647 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:195648 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:135649 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:195650 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:135651 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:415652 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:225653
bncce36dca22015-04-21 22:11:235654 // Fetch https://www.example.org/2 via HTTP.
5655 const char get2[] =
5656 "GET /2 HTTP/1.1\r\n"
5657 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:225658 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135659 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:195660 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:225661 const char resp2[] = "HTTP/1.1 200 OK\r\n"
5662 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135663 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:195664 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:135665 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:195666 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:225667
5668 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415669 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
5670 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:225671 };
5672
5673 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415674 CreateMockRead(conn_resp1, 1, ASYNC),
5675 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:465676 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415677 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:465678 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415679 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:225680 };
5681
Ryan Sleevib8d7ea02018-05-07 20:01:015682 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:505683 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225684
5685 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365686 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505687 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225688 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:505689 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:225690
5691 TestCompletionCallback callback;
5692
bnc87dcefc2017-05-25 12:47:585693 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195694 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205695 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015696 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225697
5698 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015699 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225700
5701 LoadTimingInfo load_timing_info;
5702 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5703 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5704
5705 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525706 ASSERT_TRUE(response);
5707 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:225708 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5709
5710 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:445711 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
[email protected]90499482013-06-01 00:39:505712 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225713 trans.reset();
5714
bnc87dcefc2017-05-25 12:47:585715 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195716 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205717 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015718 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:225719
[email protected]f6c63db52013-02-02 00:35:225720 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:015721 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:225722
5723 LoadTimingInfo load_timing_info2;
5724 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5725 TestLoadTimingReused(load_timing_info2);
5726
5727 // The requests should have the same ID.
5728 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5729
[email protected]90499482013-06-01 00:39:505730 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:225731}
5732
5733// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
5734// Proxy to different servers.
bncd16676a2016-07-20 16:23:015735TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:225736 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495737 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5738 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515739 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075740 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095741 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:505742 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:225743
5744 HttpRequestInfo request1;
5745 request1.method = "GET";
bncce36dca22015-04-21 22:11:235746 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:225747 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105748 request1.traffic_annotation =
5749 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225750
5751 HttpRequestInfo request2;
5752 request2.method = "GET";
bncce36dca22015-04-21 22:11:235753 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:225754 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:105755 request2.traffic_annotation =
5756 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:225757
bncce36dca22015-04-21 22:11:235758 // http://www.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:135759 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:235760 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:135761 spdy::SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:155762 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:135763 spdy::SpdySerializedFrame get_resp1(
5764 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
5765 spdy::SpdySerializedFrame body1(
5766 spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:385767 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:225768
bncce36dca22015-04-21 22:11:235769 // http://mail.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:135770 spdy::SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:235771 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:135772 spdy::SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:155773 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:135774 spdy::SpdySerializedFrame get_resp2(
5775 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
5776 spdy::SpdySerializedFrame body2(
5777 spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:225778
5779 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415780 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:225781 };
5782
5783 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415784 CreateMockRead(get_resp1, 1, ASYNC),
5785 CreateMockRead(body1, 2, ASYNC),
5786 CreateMockRead(get_resp2, 4, ASYNC),
5787 CreateMockRead(body2, 5, ASYNC),
5788 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:225789 };
5790
Ryan Sleevib8d7ea02018-05-07 20:01:015791 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:505792 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:225793
5794 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365795 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:505796 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:225797
5798 TestCompletionCallback callback;
5799
bnc87dcefc2017-05-25 12:47:585800 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:195801 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205802 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015803 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225804
5805 LoadTimingInfo load_timing_info;
5806 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
5807 TestLoadTimingNotReused(load_timing_info,
5808 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5809
5810 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:525811 ASSERT_TRUE(response);
5812 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025813 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:225814
5815 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:445816 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
mmenke11eb5152015-06-09 14:50:505817 rv = trans->Read(buf.get(), 256, callback.callback());
5818 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225819 // Delete the first request, so the second one can reuse the socket.
5820 trans.reset();
5821
bnc691fda62016-08-12 00:43:165822 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:205823 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015824 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:225825
5826 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:165827 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:225828 TestLoadTimingReused(load_timing_info2);
5829
5830 // The requests should have the same ID.
5831 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
5832
bnc691fda62016-08-12 00:43:165833 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:505834 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:225835}
5836
[email protected]2df19bb2010-08-25 20:13:465837// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:015838TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:465839 HttpRequestInfo request;
5840 request.method = "GET";
bncce36dca22015-04-21 22:11:235841 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:465842 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:295843 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:105844 request.traffic_annotation =
5845 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:465846
[email protected]79cb5c12011-09-12 13:12:045847 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495848 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5849 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515850 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075851 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095852 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275853
[email protected]2df19bb2010-08-25 20:13:465854 // Since we have proxy, should use full url
5855 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:165856 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5857 "Host: www.example.org\r\n"
5858 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465859
bnc691fda62016-08-12 00:43:165860 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:235861 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:165862 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
5863 "Host: www.example.org\r\n"
5864 "Proxy-Connection: keep-alive\r\n"
5865 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465866 };
5867
5868 // The proxy responds to the GET with a 407, using a persistent
5869 // connection.
5870 MockRead data_reads1[] = {
5871 // No credentials.
5872 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
5873 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
5874 MockRead("Proxy-Connection: keep-alive\r\n"),
5875 MockRead("Content-Length: 0\r\n\r\n"),
5876
5877 MockRead("HTTP/1.1 200 OK\r\n"),
5878 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5879 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065880 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465881 };
5882
Ryan Sleevib8d7ea02018-05-07 20:01:015883 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075884 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065885 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075886 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465887
[email protected]49639fa2011-12-20 23:22:415888 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465889
bnc691fda62016-08-12 00:43:165890 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505891
bnc691fda62016-08-12 00:43:165892 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015893 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465894
5895 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015896 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465897
[email protected]58e32bb2013-01-21 18:23:255898 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165899 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255900 TestLoadTimingNotReused(load_timing_info,
5901 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5902
bnc691fda62016-08-12 00:43:165903 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525904 ASSERT_TRUE(response);
5905 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:465906 EXPECT_EQ(407, response->headers->response_code());
5907 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
asanka098c0092016-06-16 20:18:435908 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]2df19bb2010-08-25 20:13:465909
[email protected]49639fa2011-12-20 23:22:415910 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:465911
bnc691fda62016-08-12 00:43:165912 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015913 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465914
5915 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015916 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465917
[email protected]58e32bb2013-01-21 18:23:255918 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:165919 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255920 // Retrying with HTTP AUTH is considered to be reusing a socket.
5921 TestLoadTimingReused(load_timing_info);
5922
bnc691fda62016-08-12 00:43:165923 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525924 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465925
5926 EXPECT_TRUE(response->headers->IsKeepAlive());
5927 EXPECT_EQ(200, response->headers->response_code());
5928 EXPECT_EQ(100, response->headers->GetContentLength());
5929 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5930
5931 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:525932 EXPECT_FALSE(response->auth_challenge);
[email protected]2df19bb2010-08-25 20:13:465933}
5934
[email protected]23e482282013-06-14 16:08:025935void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:085936 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:425937 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:085938 request.method = "GET";
bncce36dca22015-04-21 22:11:235939 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:105940 request.traffic_annotation =
5941 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:085942
[email protected]cb9bf6ca2011-01-28 13:15:275943 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495944 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5945 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:095946 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:275947
[email protected]c744cf22009-02-27 07:28:085948 // Since we have proxy, should try to establish tunnel.
5949 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:175950 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5951 "Host: www.example.org:443\r\n"
5952 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:085953 };
5954
5955 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:235956 status, MockRead("Content-Length: 10\r\n\r\n"),
5957 // No response body because the test stops reading here.
5958 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:085959 };
5960
Ryan Sleevib8d7ea02018-05-07 20:01:015961 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:075962 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:085963
[email protected]49639fa2011-12-20 23:22:415964 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:085965
bnc691fda62016-08-12 00:43:165966 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505967
tfarina42834112016-09-22 13:38:205968 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:015969 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:085970
5971 rv = callback.WaitForResult();
5972 EXPECT_EQ(expected_status, rv);
5973}
5974
[email protected]23e482282013-06-14 16:08:025975void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:235976 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:085977 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:425978 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:085979}
5980
bncd16676a2016-07-20 16:23:015981TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:085982 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
5983}
5984
bncd16676a2016-07-20 16:23:015985TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:085986 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
5987}
5988
bncd16676a2016-07-20 16:23:015989TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:085990 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
5991}
5992
bncd16676a2016-07-20 16:23:015993TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:085994 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
5995}
5996
bncd16676a2016-07-20 16:23:015997TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:085998 ConnectStatusHelper(
5999 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
6000}
6001
bncd16676a2016-07-20 16:23:016002TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:086003 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
6004}
6005
bncd16676a2016-07-20 16:23:016006TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:086007 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
6008}
6009
bncd16676a2016-07-20 16:23:016010TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:086011 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
6012}
6013
bncd16676a2016-07-20 16:23:016014TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:086015 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
6016}
6017
bncd16676a2016-07-20 16:23:016018TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:086019 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
6020}
6021
bncd16676a2016-07-20 16:23:016022TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086023 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6024}
6025
bncd16676a2016-07-20 16:23:016026TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086027 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6028}
6029
bncd16676a2016-07-20 16:23:016030TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086031 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6032}
6033
bncd16676a2016-07-20 16:23:016034TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086035 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6036}
6037
bncd16676a2016-07-20 16:23:016038TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086039 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6040}
6041
bncd16676a2016-07-20 16:23:016042TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086043 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6044}
6045
bncd16676a2016-07-20 16:23:016046TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376047 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6048}
6049
bncd16676a2016-07-20 16:23:016050TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086051 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6052}
6053
bncd16676a2016-07-20 16:23:016054TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086055 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6056}
6057
bncd16676a2016-07-20 16:23:016058TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086059 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6060}
6061
bncd16676a2016-07-20 16:23:016062TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086063 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6064}
6065
bncd16676a2016-07-20 16:23:016066TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086067 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6068}
6069
bncd16676a2016-07-20 16:23:016070TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086071 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6072}
6073
bncd16676a2016-07-20 16:23:016074TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086075 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6076}
6077
bncd16676a2016-07-20 16:23:016078TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086079 ConnectStatusHelperWithExpectedStatus(
6080 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546081 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086082}
6083
bncd16676a2016-07-20 16:23:016084TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086085 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6086}
6087
bncd16676a2016-07-20 16:23:016088TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086089 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6090}
6091
bncd16676a2016-07-20 16:23:016092TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086093 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6094}
6095
bncd16676a2016-07-20 16:23:016096TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086097 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6098}
6099
bncd16676a2016-07-20 16:23:016100TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086101 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6102}
6103
bncd16676a2016-07-20 16:23:016104TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086105 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6106}
6107
bncd16676a2016-07-20 16:23:016108TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086109 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6110}
6111
bncd16676a2016-07-20 16:23:016112TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086113 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6114}
6115
bncd16676a2016-07-20 16:23:016116TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086117 ConnectStatusHelper(
6118 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6119}
6120
bncd16676a2016-07-20 16:23:016121TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086122 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6123}
6124
bncd16676a2016-07-20 16:23:016125TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086126 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6127}
6128
bncd16676a2016-07-20 16:23:016129TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086130 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6131}
6132
bncd16676a2016-07-20 16:23:016133TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086134 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6135}
6136
bncd16676a2016-07-20 16:23:016137TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086138 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6139}
6140
bncd16676a2016-07-20 16:23:016141TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086142 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6143}
6144
bncd16676a2016-07-20 16:23:016145TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086146 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6147}
6148
[email protected]038e9a32008-10-08 22:40:166149// Test the flow when both the proxy server AND origin server require
6150// authentication. Again, this uses basic auth for both since that is
6151// the simplest to mock.
bncd16676a2016-07-20 16:23:016152TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276153 HttpRequestInfo request;
6154 request.method = "GET";
bncce36dca22015-04-21 22:11:236155 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106156 request.traffic_annotation =
6157 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:276158
[email protected]038e9a32008-10-08 22:40:166159 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496160 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6161 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096162 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:076163
bnc691fda62016-08-12 00:43:166164 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:166165
[email protected]f9ee6b52008-11-08 06:46:236166 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:236167 MockWrite(
6168 "GET http://www.example.org/ HTTP/1.1\r\n"
6169 "Host: www.example.org\r\n"
6170 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:236171 };
6172
[email protected]038e9a32008-10-08 22:40:166173 MockRead data_reads1[] = {
6174 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
6175 // Give a couple authenticate options (only the middle one is actually
6176 // supported).
[email protected]22927ad2009-09-21 19:56:196177 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:166178 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6179 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
6180 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6181 // Large content-length -- won't matter, as connection will be reset.
6182 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066183 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:166184 };
6185
bnc691fda62016-08-12 00:43:166186 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:166187 // request we should be issuing -- the final header line contains the
6188 // proxy's credentials.
6189 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:236190 MockWrite(
6191 "GET http://www.example.org/ HTTP/1.1\r\n"
6192 "Host: www.example.org\r\n"
6193 "Proxy-Connection: keep-alive\r\n"
6194 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166195 };
6196
6197 // Now the proxy server lets the request pass through to origin server.
6198 // The origin server responds with a 401.
6199 MockRead data_reads2[] = {
6200 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
6201 // Note: We are using the same realm-name as the proxy server. This is
6202 // completely valid, as realms are unique across hosts.
6203 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6204 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6205 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066206 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:166207 };
6208
bnc691fda62016-08-12 00:43:166209 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:166210 // the credentials for both the proxy and origin server.
6211 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:236212 MockWrite(
6213 "GET http://www.example.org/ HTTP/1.1\r\n"
6214 "Host: www.example.org\r\n"
6215 "Proxy-Connection: keep-alive\r\n"
6216 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
6217 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:166218 };
6219
6220 // Lastly we get the desired content.
6221 MockRead data_reads3[] = {
6222 MockRead("HTTP/1.0 200 OK\r\n"),
6223 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6224 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066225 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:166226 };
6227
Ryan Sleevib8d7ea02018-05-07 20:01:016228 StaticSocketDataProvider data1(data_reads1, data_writes1);
6229 StaticSocketDataProvider data2(data_reads2, data_writes2);
6230 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:076231 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6232 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6233 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:166234
[email protected]49639fa2011-12-20 23:22:416235 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:166236
tfarina42834112016-09-22 13:38:206237 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016238 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166239
6240 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016241 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166242
bnc691fda62016-08-12 00:43:166243 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526244 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046245 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166246
[email protected]49639fa2011-12-20 23:22:416247 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:166248
bnc691fda62016-08-12 00:43:166249 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016250 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166251
6252 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016253 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166254
bnc691fda62016-08-12 00:43:166255 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526256 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046257 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]038e9a32008-10-08 22:40:166258
[email protected]49639fa2011-12-20 23:22:416259 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:166260
bnc691fda62016-08-12 00:43:166261 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
6262 callback3.callback());
robpercival214763f2016-07-01 23:27:016263 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:166264
6265 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016266 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:166267
bnc691fda62016-08-12 00:43:166268 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526269 EXPECT_FALSE(response->auth_challenge);
[email protected]038e9a32008-10-08 22:40:166270 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:166271}
[email protected]4ddaf2502008-10-23 18:26:196272
[email protected]ea9dc9a2009-09-05 00:43:326273// For the NTLM implementation using SSPI, we skip the NTLM tests since we
6274// can't hook into its internals to cause it to generate predictable NTLM
6275// authorization headers.
6276#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376277// The NTLM authentication unit tests are based on known test data from the
6278// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
6279// flow rather than the implementation of the NTLM protocol. See net/ntlm
6280// for the implementation and testing of the protocol.
6281//
6282// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:296283
6284// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556285TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:426286 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:246287 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556288 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:106289 request.traffic_annotation =
6290 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:546291
6292 // Ensure load is not disrupted by flags which suppress behaviour specific
6293 // to other auth schemes.
6294 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:246295
Zentaro Kavanagh6ccee512017-09-28 18:34:096296 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6297 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096298 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276299
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376300 // Generate the NTLM messages based on known test data.
6301 std::string negotiate_msg;
6302 std::string challenge_msg;
6303 std::string authenticate_msg;
6304 base::Base64Encode(
6305 base::StringPiece(
6306 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6307 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6308 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556309 base::Base64Encode(
6310 base::StringPiece(
6311 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6312 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6313 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376314 base::Base64Encode(
6315 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096316 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556317 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6318 arraysize(
6319 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376320 &authenticate_msg);
6321
[email protected]3f918782009-02-28 01:29:246322 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556323 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6324 "Host: server\r\n"
6325 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246326 };
6327
6328 MockRead data_reads1[] = {
6329 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046330 // Negotiate and NTLM are often requested together. However, we only want
6331 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6332 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:246333 MockRead("WWW-Authenticate: NTLM\r\n"),
6334 MockRead("Connection: close\r\n"),
6335 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366336 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246337 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:246338 };
6339
6340 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166341 // After restarting with a null identity, this is the
6342 // request we should be issuing -- the final header line contains a Type
6343 // 1 message.
6344 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556345 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166346 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376347 "Authorization: NTLM "),
6348 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246349
bnc691fda62016-08-12 00:43:166350 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376351 // (using correct credentials). The second request continues on the
6352 // same connection.
bnc691fda62016-08-12 00:43:166353 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556354 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166355 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376356 "Authorization: NTLM "),
6357 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:246358 };
6359
6360 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:026361 // The origin server responds with a Type 2 message.
6362 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376363 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6364 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026365 MockRead("Content-Type: text/html\r\n\r\n"),
6366 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:246367
Bence Béky1e4ef192017-09-18 19:58:026368 // Lastly we get the desired content.
6369 MockRead("HTTP/1.1 200 OK\r\n"),
6370 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6371 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:246372 };
6373
Ryan Sleevib8d7ea02018-05-07 20:01:016374 StaticSocketDataProvider data1(data_reads1, data_writes1);
6375 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:076376 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6377 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:246378
Bence Béky83eb3512017-09-05 12:56:096379 SSLSocketDataProvider ssl1(ASYNC, OK);
6380 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6381 SSLSocketDataProvider ssl2(ASYNC, OK);
6382 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6383
[email protected]49639fa2011-12-20 23:22:416384 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:246385
bnc691fda62016-08-12 00:43:166386 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506387
tfarina42834112016-09-22 13:38:206388 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016389 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246390
6391 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016392 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246393
bnc691fda62016-08-12 00:43:166394 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226395
bnc691fda62016-08-12 00:43:166396 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526397 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046398 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]3f918782009-02-28 01:29:246399
[email protected]49639fa2011-12-20 23:22:416400 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:256401
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376402 rv = trans.RestartWithAuth(
6403 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6404 callback2.callback());
robpercival214763f2016-07-01 23:27:016405 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256406
6407 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016408 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256409
bnc691fda62016-08-12 00:43:166410 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256411
bnc691fda62016-08-12 00:43:166412 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526413 ASSERT_TRUE(response);
6414 EXPECT_FALSE(response->auth_challenge);
[email protected]10af5fe72011-01-31 16:17:256415
[email protected]49639fa2011-12-20 23:22:416416 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:246417
bnc691fda62016-08-12 00:43:166418 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016419 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:246420
[email protected]0757e7702009-03-27 04:00:226421 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016422 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:246423
bnc691fda62016-08-12 00:43:166424 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526425 ASSERT_TRUE(response);
6426 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026427 EXPECT_EQ(14, response->headers->GetContentLength());
6428
6429 std::string response_data;
6430 rv = ReadTransaction(&trans, &response_data);
6431 EXPECT_THAT(rv, IsOk());
6432 EXPECT_EQ("Please Login\r\n", response_data);
6433
6434 EXPECT_TRUE(data1.AllReadDataConsumed());
6435 EXPECT_TRUE(data1.AllWriteDataConsumed());
6436 EXPECT_TRUE(data2.AllReadDataConsumed());
6437 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:246438}
6439
[email protected]385a4672009-03-11 22:21:296440// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:556441TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:426442 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:296443 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:556444 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e2018-02-07 07:41:106445 request.traffic_annotation =
6446 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:296447
Zentaro Kavanagh6ccee512017-09-28 18:34:096448 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6449 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:096450 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276451
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376452 // Generate the NTLM messages based on known test data.
6453 std::string negotiate_msg;
6454 std::string challenge_msg;
6455 std::string authenticate_msg;
6456 base::Base64Encode(
6457 base::StringPiece(
6458 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6459 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6460 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556461 base::Base64Encode(
6462 base::StringPiece(
6463 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6464 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6465 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376466 base::Base64Encode(
6467 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096468 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556469 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6470 arraysize(
6471 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376472 &authenticate_msg);
6473
6474 // The authenticate message when |kWrongPassword| is sent.
6475 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556476 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
6477 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
6478 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
6479 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
6480 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
6481 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376482
Zentaro Kavanagh1890a3d2018-01-29 19:52:556483 // Sanity check that it's the same length as the correct authenticate message
6484 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376485 ASSERT_EQ(authenticate_msg.length(),
6486 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:556487 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376488
[email protected]385a4672009-03-11 22:21:296489 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:556490 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
6491 "Host: server\r\n"
6492 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296493 };
6494
6495 MockRead data_reads1[] = {
6496 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:046497 // Negotiate and NTLM are often requested together. However, we only want
6498 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
6499 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:296500 MockRead("WWW-Authenticate: NTLM\r\n"),
6501 MockRead("Connection: close\r\n"),
6502 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:366503 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296504 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296505 };
6506
6507 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:166508 // After restarting with a null identity, this is the
6509 // request we should be issuing -- the final header line contains a Type
6510 // 1 message.
6511 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556512 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166513 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376514 "Authorization: NTLM "),
6515 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296516
bnc691fda62016-08-12 00:43:166517 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376518 // (using incorrect credentials). The second request continues on the
6519 // same connection.
bnc691fda62016-08-12 00:43:166520 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556521 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166522 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376523 "Authorization: NTLM "),
6524 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296525 };
6526
6527 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376528 // The origin server responds with a Type 2 message.
6529 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6530 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6531 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
6532 MockRead("Content-Type: text/html\r\n\r\n"),
6533 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296534
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376535 // Wrong password.
6536 MockRead("HTTP/1.1 401 Access Denied\r\n"),
6537 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
6538 MockRead("Content-Length: 42\r\n"),
6539 MockRead("Content-Type: text/html\r\n\r\n"),
6540 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:296541 };
6542
6543 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:166544 // After restarting with a null identity, this is the
6545 // request we should be issuing -- the final header line contains a Type
6546 // 1 message.
6547 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556548 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166549 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376550 "Authorization: NTLM "),
6551 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296552
bnc691fda62016-08-12 00:43:166553 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6554 // (the credentials for the origin server). The second request continues
6555 // on the same connection.
6556 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556557 "Host: server\r\n"
bnc691fda62016-08-12 00:43:166558 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376559 "Authorization: NTLM "),
6560 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:296561 };
6562
6563 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:026564 // The origin server responds with a Type 2 message.
6565 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376566 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6567 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026568 MockRead("Content-Type: text/html\r\n\r\n"),
6569 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:296570
Bence Béky1e4ef192017-09-18 19:58:026571 // Lastly we get the desired content.
6572 MockRead("HTTP/1.1 200 OK\r\n"),
6573 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
6574 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:296575 };
6576
Ryan Sleevib8d7ea02018-05-07 20:01:016577 StaticSocketDataProvider data1(data_reads1, data_writes1);
6578 StaticSocketDataProvider data2(data_reads2, data_writes2);
6579 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:076580 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6581 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6582 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:296583
Bence Béky83eb3512017-09-05 12:56:096584 SSLSocketDataProvider ssl1(ASYNC, OK);
6585 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6586 SSLSocketDataProvider ssl2(ASYNC, OK);
6587 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6588 SSLSocketDataProvider ssl3(ASYNC, OK);
6589 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6590
[email protected]49639fa2011-12-20 23:22:416591 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:296592
bnc691fda62016-08-12 00:43:166593 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506594
tfarina42834112016-09-22 13:38:206595 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016596 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296597
6598 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016599 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296600
bnc691fda62016-08-12 00:43:166601 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:296602
bnc691fda62016-08-12 00:43:166603 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526604 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046605 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]385a4672009-03-11 22:21:296606
[email protected]49639fa2011-12-20 23:22:416607 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:296608
[email protected]0757e7702009-03-27 04:00:226609 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376610 rv = trans.RestartWithAuth(
6611 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
6612 callback2.callback());
robpercival214763f2016-07-01 23:27:016613 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:296614
[email protected]10af5fe72011-01-31 16:17:256615 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016616 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:296617
bnc691fda62016-08-12 00:43:166618 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:416619 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:166620 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:016621 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256622 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:016623 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:166624 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:226625
bnc691fda62016-08-12 00:43:166626 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526627 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:046628 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
[email protected]0757e7702009-03-27 04:00:226629
[email protected]49639fa2011-12-20 23:22:416630 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:226631
6632 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376633 rv = trans.RestartWithAuth(
6634 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6635 callback4.callback());
robpercival214763f2016-07-01 23:27:016636 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:256637
6638 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:016639 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:256640
bnc691fda62016-08-12 00:43:166641 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:256642
[email protected]49639fa2011-12-20 23:22:416643 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:256644
6645 // One more roundtrip
bnc691fda62016-08-12 00:43:166646 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:016647 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:226648
6649 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:016650 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:226651
bnc691fda62016-08-12 00:43:166652 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526653 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026654 EXPECT_EQ(14, response->headers->GetContentLength());
6655
6656 std::string response_data;
6657 rv = ReadTransaction(&trans, &response_data);
6658 EXPECT_THAT(rv, IsOk());
6659 EXPECT_EQ("Please Login\r\n", response_data);
6660
6661 EXPECT_TRUE(data1.AllReadDataConsumed());
6662 EXPECT_TRUE(data1.AllWriteDataConsumed());
6663 EXPECT_TRUE(data2.AllReadDataConsumed());
6664 EXPECT_TRUE(data2.AllWriteDataConsumed());
6665 EXPECT_TRUE(data3.AllReadDataConsumed());
6666 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:296667}
Bence Béky83eb3512017-09-05 12:56:096668
Bence Béky3238f2e12017-09-22 22:44:496669// Server requests NTLM authentication, which is not supported over HTTP/2.
6670// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:096671TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:096672 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6673 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:096674
Zentaro Kavanagh1890a3d2018-01-29 19:52:556675 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:096676
6677 HttpRequestInfo request;
6678 request.method = "GET";
6679 request.url = GURL(kUrl);
Ramin Halavatib5e433e2018-02-07 07:41:106680 request.traffic_annotation =
6681 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:096682
6683 // First request without credentials.
Ryan Hamilton0239aac2018-05-19 00:03:136684 spdy::SpdyHeaderBlock request_headers0(
6685 spdy_util_.ConstructGetHeaderBlock(kUrl));
6686 spdy::SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
Bence Béky83eb3512017-09-05 12:56:096687 1, std::move(request_headers0), LOWEST, true));
6688
Ryan Hamilton0239aac2018-05-19 00:03:136689 spdy::SpdyHeaderBlock response_headers0;
6690 response_headers0[spdy::kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:096691 response_headers0["www-authenticate"] = "NTLM";
Ryan Hamilton0239aac2018-05-19 00:03:136692 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
Bence Béky83eb3512017-09-05 12:56:096693 1, std::move(response_headers0), true));
6694
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376695 // Stream 1 is closed.
6696 spdy_util_.UpdateWithStreamDestruction(1);
6697
6698 // Generate the NTLM messages based on known test data.
6699 std::string negotiate_msg;
6700 std::string challenge_msg;
6701 std::string authenticate_msg;
6702 base::Base64Encode(
6703 base::StringPiece(
6704 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6705 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6706 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:556707 base::Base64Encode(
6708 base::StringPiece(
6709 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6710 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6711 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376712 base::Base64Encode(
6713 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:096714 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:556715 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6716 arraysize(
6717 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376718 &authenticate_msg);
6719
6720 // Retry with authorization header.
Ryan Hamilton0239aac2018-05-19 00:03:136721 spdy::SpdyHeaderBlock request_headers1(
6722 spdy_util_.ConstructGetHeaderBlock(kUrl));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376723 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
Ryan Hamilton0239aac2018-05-19 00:03:136724 spdy::SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376725 3, std::move(request_headers1), LOWEST, true));
6726
Ryan Hamilton0239aac2018-05-19 00:03:136727 spdy::SpdySerializedFrame rst(
6728 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376729
Bence Béky3238f2e12017-09-22 22:44:496730 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
6731 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:096732
6733 // Retry yet again using HTTP/1.1.
6734 MockWrite writes1[] = {
6735 // After restarting with a null identity, this is the
6736 // request we should be issuing -- the final header line contains a Type
6737 // 1 message.
6738 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556739 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096740 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376741 "Authorization: NTLM "),
6742 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096743
6744 // After calling trans.RestartWithAuth(), we should send a Type 3 message
6745 // (the credentials for the origin server). The second request continues
6746 // on the same connection.
6747 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:556748 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:096749 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376750 "Authorization: NTLM "),
6751 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:096752 };
6753
6754 MockRead reads1[] = {
6755 // The origin server responds with a Type 2 message.
6756 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376757 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
6758 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:096759 MockRead("Content-Type: text/html\r\n\r\n"),
6760 MockRead("You are not authorized to view this page\r\n"),
6761
6762 // Lastly we get the desired content.
6763 MockRead("HTTP/1.1 200 OK\r\n"),
6764 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:026765 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:096766 };
Ryan Sleevib8d7ea02018-05-07 20:01:016767 SequencedSocketData data0(reads0, writes0);
6768 StaticSocketDataProvider data1(reads1, writes1);
Bence Béky83eb3512017-09-05 12:56:096769 session_deps_.socket_factory->AddSocketDataProvider(&data0);
6770 session_deps_.socket_factory->AddSocketDataProvider(&data1);
6771
6772 SSLSocketDataProvider ssl0(ASYNC, OK);
6773 ssl0.next_proto = kProtoHTTP2;
6774 SSLSocketDataProvider ssl1(ASYNC, OK);
6775 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
6776 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
6777
6778 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6779 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6780
6781 TestCompletionCallback callback1;
6782 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
6783 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6784
6785 rv = callback1.WaitForResult();
6786 EXPECT_THAT(rv, IsOk());
6787
6788 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6789
6790 const HttpResponseInfo* response = trans.GetResponseInfo();
6791 ASSERT_TRUE(response);
6792 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
6793
6794 TestCompletionCallback callback2;
6795
Zentaro Kavanagh5b27a6e22017-09-25 23:00:376796 rv = trans.RestartWithAuth(
6797 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6798 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:096799 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6800
6801 rv = callback2.WaitForResult();
6802 EXPECT_THAT(rv, IsOk());
6803
6804 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6805
6806 response = trans.GetResponseInfo();
6807 ASSERT_TRUE(response);
6808 EXPECT_FALSE(response->auth_challenge);
6809
6810 TestCompletionCallback callback3;
6811
6812 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
6813 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6814
6815 rv = callback3.WaitForResult();
6816 EXPECT_THAT(rv, IsOk());
6817
6818 response = trans.GetResponseInfo();
6819 ASSERT_TRUE(response);
6820 EXPECT_FALSE(response->auth_challenge);
Bence Béky1e4ef192017-09-18 19:58:026821 EXPECT_EQ(14, response->headers->GetContentLength());
6822
6823 std::string response_data;
6824 rv = ReadTransaction(&trans, &response_data);
6825 EXPECT_THAT(rv, IsOk());
6826 EXPECT_EQ("Please Login\r\n", response_data);
6827
6828 EXPECT_TRUE(data0.AllReadDataConsumed());
6829 EXPECT_TRUE(data0.AllWriteDataConsumed());
6830 EXPECT_TRUE(data1.AllReadDataConsumed());
6831 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:096832}
David Benjamin5cb91132018-04-06 05:54:496833
6834// Test that, if we have an NTLM proxy and the origin resets the connection, we
6835// do no retry forever checking for TLS version interference. This is a
6836// regression test for https://crbug.com/823387.
6837TEST_F(HttpNetworkTransactionTest, NTLMProxyTLSHandshakeReset) {
6838 // The NTLM test data expects the proxy to be named 'server'. The origin is
6839 // https://origin/.
6840 session_deps_.proxy_resolution_service =
6841 ProxyResolutionService::CreateFixedFromPacResult(
6842 "PROXY server", TRAFFIC_ANNOTATION_FOR_TESTS);
6843
6844 SSLConfig config;
6845 config.version_max = SSL_PROTOCOL_VERSION_TLS1_3;
6846 session_deps_.ssl_config_service =
Ryan Sleevib8449e02018-07-15 04:31:076847 std::make_unique<TestSSLConfigService>(config);
David Benjamin5cb91132018-04-06 05:54:496848
6849 HttpRequestInfo request;
6850 request.method = "GET";
6851 request.url = GURL("https://origin/");
6852 request.traffic_annotation =
6853 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6854
6855 // Ensure load is not disrupted by flags which suppress behaviour specific
6856 // to other auth schemes.
6857 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
6858
6859 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
6860 MockGetMSTime, MockGenerateRandom, MockGetHostName);
6861 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6862
6863 // Generate the NTLM messages based on known test data.
6864 std::string negotiate_msg;
6865 std::string challenge_msg;
6866 std::string authenticate_msg;
6867 base::Base64Encode(
6868 base::StringPiece(
6869 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
6870 arraysize(ntlm::test::kExpectedNegotiateMsg)),
6871 &negotiate_msg);
6872 base::Base64Encode(
6873 base::StringPiece(
6874 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
6875 arraysize(ntlm::test::kChallengeMsgFromSpecV2)),
6876 &challenge_msg);
6877 base::Base64Encode(
6878 base::StringPiece(
6879 reinterpret_cast<const char*>(
6880 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
6881 arraysize(
6882 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
6883 &authenticate_msg);
6884
6885 MockWrite data_writes[] = {
6886 // The initial CONNECT request.
6887 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
6888 "Host: origin:443\r\n"
6889 "Proxy-Connection: keep-alive\r\n\r\n"),
6890
6891 // After restarting with an identity.
6892 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
6893 "Host: origin:443\r\n"
6894 "Proxy-Connection: keep-alive\r\n"
6895 "Proxy-Authorization: NTLM "),
6896 MockWrite(negotiate_msg.c_str()),
6897 // End headers.
6898 MockWrite("\r\n\r\n"),
6899
6900 // The second restart.
6901 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
6902 "Host: origin:443\r\n"
6903 "Proxy-Connection: keep-alive\r\n"
6904 "Proxy-Authorization: NTLM "),
6905 MockWrite(authenticate_msg.c_str()),
6906 // End headers.
6907 MockWrite("\r\n\r\n"),
6908 };
6909
6910 MockRead data_reads[] = {
6911 // The initial NTLM response.
6912 MockRead("HTTP/1.1 407 Access Denied\r\n"
6913 "Content-Length: 0\r\n"
6914 "Proxy-Authenticate: NTLM\r\n\r\n"),
6915
6916 // The NTLM challenge message.
6917 MockRead("HTTP/1.1 407 Access Denied\r\n"
6918 "Content-Length: 0\r\n"
6919 "Proxy-Authenticate: NTLM "),
6920 MockRead(challenge_msg.c_str()),
6921 // End headers.
6922 MockRead("\r\n\r\n"),
6923
6924 // Finally the tunnel is established.
6925 MockRead("HTTP/1.1 200 Connected\r\n\r\n"),
6926 };
6927
Ryan Sleevib8d7ea02018-05-07 20:01:016928 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:496929 SSLSocketDataProvider data_ssl(ASYNC, ERR_CONNECTION_RESET);
Helen Li48f117e2018-05-29 20:38:406930 data_ssl.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_3;
Ryan Sleevib8d7ea02018-05-07 20:01:016931 StaticSocketDataProvider data2(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:496932 SSLSocketDataProvider data_ssl2(ASYNC, ERR_CONNECTION_RESET);
6933 session_deps_.socket_factory->AddSocketDataProvider(&data);
6934 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl);
6935 session_deps_.socket_factory->AddSocketDataProvider(&data2);
6936 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl2);
6937
6938 // Start the transaction. The proxy responds with an NTLM authentication
6939 // request.
6940 TestCompletionCallback callback;
6941 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
6942 int rv = callback.GetResult(
6943 trans.Start(&request, callback.callback(), NetLogWithSource()));
6944
6945 EXPECT_THAT(rv, IsOk());
6946 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
6947 const HttpResponseInfo* response = trans.GetResponseInfo();
6948 ASSERT_TRUE(response);
6949 EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge.get()));
6950
6951 // Configure credentials. The proxy responds with the challenge message.
6952 rv = callback.GetResult(trans.RestartWithAuth(
6953 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
6954 callback.callback()));
6955 EXPECT_THAT(rv, IsOk());
6956 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6957 response = trans.GetResponseInfo();
6958 ASSERT_TRUE(response);
6959 EXPECT_FALSE(response->auth_challenge);
6960
6961 // Restart once more. The tunnel will be established and the the SSL handshake
6962 // will reset. The TLS 1.3 version interference probe will then kick in and
6963 // restart the process. The proxy responds with another NTLM authentiation
6964 // request, but we don't need to provide credentials as the cached ones work/
6965 rv = callback.GetResult(
6966 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
6967 EXPECT_THAT(rv, IsOk());
6968 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6969 response = trans.GetResponseInfo();
6970 ASSERT_TRUE(response);
6971 EXPECT_FALSE(response->auth_challenge);
6972
6973 // The proxy responds with the NTLM challenge message.
6974 rv = callback.GetResult(
6975 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
6976 EXPECT_THAT(rv, IsOk());
6977 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
6978 response = trans.GetResponseInfo();
6979 ASSERT_TRUE(response);
6980 EXPECT_FALSE(response->auth_challenge);
6981
6982 // Send the NTLM authenticate message. The tunnel is established and the
6983 // handshake resets again. We should not retry again.
6984 rv = callback.GetResult(
6985 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
6986 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
6987}
6988
[email protected]ea9dc9a2009-09-05 00:43:326989#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:296990
[email protected]4ddaf2502008-10-23 18:26:196991// Test reading a server response which has only headers, and no body.
6992// After some maximum number of bytes is consumed, the transaction should
6993// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:016994TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:426995 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:196996 request.method = "GET";
bncce36dca22015-04-21 22:11:236997 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:106998 request.traffic_annotation =
6999 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:197000
danakj1fd259a02016-04-16 03:17:097001 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167002 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277003
[email protected]b75b7b2f2009-10-06 00:54:537004 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:437005 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:537006 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:197007
7008 MockRead data_reads[] = {
7009 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:067010 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:197011 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:067012 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:197013 };
Ryan Sleevib8d7ea02018-05-07 20:01:017014 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077015 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:197016
[email protected]49639fa2011-12-20 23:22:417017 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:197018
tfarina42834112016-09-22 13:38:207019 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017020 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:197021
7022 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017023 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:197024}
[email protected]f4e426b2008-11-05 00:24:497025
7026// Make sure that we don't try to reuse a TCPClientSocket when failing to
7027// establish tunnel.
7028// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:017029TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:277030 HttpRequestInfo request;
7031 request.method = "GET";
bncce36dca22015-04-21 22:11:237032 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107033 request.traffic_annotation =
7034 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:277035
[email protected]f4e426b2008-11-05 00:24:497036 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:497037 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
7038 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]db8f44c2008-12-13 04:52:017039
danakj1fd259a02016-04-16 03:17:097040 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:497041
bnc87dcefc2017-05-25 12:47:587042 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197043 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:497044
[email protected]f4e426b2008-11-05 00:24:497045 // Since we have proxy, should try to establish tunnel.
7046 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:177047 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7048 "Host: www.example.org:443\r\n"
7049 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:497050 };
7051
[email protected]77848d12008-11-14 00:00:227052 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:497053 // connection. Usually a proxy would return 501 (not implemented),
7054 // or 200 (tunnel established).
7055 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:237056 MockRead("HTTP/1.1 404 Not Found\r\n"),
7057 MockRead("Content-Length: 10\r\n\r\n"),
7058 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:497059 };
7060
Ryan Sleevib8d7ea02018-05-07 20:01:017061 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:077062 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:497063
[email protected]49639fa2011-12-20 23:22:417064 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:497065
tfarina42834112016-09-22 13:38:207066 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017067 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:497068
7069 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017070 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:497071
[email protected]b4404c02009-04-10 16:38:527072 // Empty the current queue. This is necessary because idle sockets are
7073 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557074 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527075
[email protected]f4e426b2008-11-05 00:24:497076 // We now check to make sure the TCPClientSocket was not added back to
7077 // the pool.
[email protected]90499482013-06-01 00:39:507078 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497079 trans.reset();
fdoray92e35a72016-06-10 15:54:557080 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497081 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507082 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497083}
[email protected]372d34a2008-11-05 21:30:517084
[email protected]1b157c02009-04-21 01:55:407085// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017086TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427087 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407088 request.method = "GET";
bncce36dca22015-04-21 22:11:237089 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107090 request.traffic_annotation =
7091 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407092
danakj1fd259a02016-04-16 03:17:097093 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277094
bnc691fda62016-08-12 00:43:167095 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277096
[email protected]1b157c02009-04-21 01:55:407097 MockRead data_reads[] = {
7098 // A part of the response body is received with the response headers.
7099 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7100 // The rest of the response body is received in two parts.
7101 MockRead("lo"),
7102 MockRead(" world"),
7103 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067104 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407105 };
7106
Ryan Sleevib8d7ea02018-05-07 20:01:017107 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077108 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407109
[email protected]49639fa2011-12-20 23:22:417110 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407111
tfarina42834112016-09-22 13:38:207112 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017113 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407114
7115 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017116 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407117
bnc691fda62016-08-12 00:43:167118 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527119 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407120
wezca1070932016-05-26 20:30:527121 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407122 std::string status_line = response->headers->GetStatusLine();
7123 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7124
[email protected]90499482013-06-01 00:39:507125 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407126
7127 std::string response_data;
bnc691fda62016-08-12 00:43:167128 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017129 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407130 EXPECT_EQ("hello world", response_data);
7131
7132 // Empty the current queue. This is necessary because idle sockets are
7133 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557134 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407135
7136 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507137 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407138}
7139
[email protected]76a505b2010-08-25 06:23:007140// Make sure that we recycle a SSL socket after reading all of the response
7141// body.
bncd16676a2016-07-20 16:23:017142TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007143 HttpRequestInfo request;
7144 request.method = "GET";
bncce36dca22015-04-21 22:11:237145 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107146 request.traffic_annotation =
7147 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007148
7149 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237150 MockWrite(
7151 "GET / HTTP/1.1\r\n"
7152 "Host: www.example.org\r\n"
7153 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007154 };
7155
7156 MockRead data_reads[] = {
7157 MockRead("HTTP/1.1 200 OK\r\n"),
7158 MockRead("Content-Length: 11\r\n\r\n"),
7159 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067160 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:007161 };
7162
[email protected]8ddf8322012-02-23 18:08:067163 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077164 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:007165
Ryan Sleevib8d7ea02018-05-07 20:01:017166 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:077167 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:007168
[email protected]49639fa2011-12-20 23:22:417169 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007170
danakj1fd259a02016-04-16 03:17:097171 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167172 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007173
tfarina42834112016-09-22 13:38:207174 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007175
robpercival214763f2016-07-01 23:27:017176 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7177 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007178
bnc691fda62016-08-12 00:43:167179 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527180 ASSERT_TRUE(response);
7181 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007182 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7183
[email protected]90499482013-06-01 00:39:507184 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007185
7186 std::string response_data;
bnc691fda62016-08-12 00:43:167187 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017188 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007189 EXPECT_EQ("hello world", response_data);
7190
7191 // Empty the current queue. This is necessary because idle sockets are
7192 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557193 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007194
7195 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507196 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007197}
7198
7199// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
7200// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:017201TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007202 HttpRequestInfo request;
7203 request.method = "GET";
bncce36dca22015-04-21 22:11:237204 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:107205 request.traffic_annotation =
7206 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007207
7208 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237209 MockWrite(
7210 "GET / HTTP/1.1\r\n"
7211 "Host: www.example.org\r\n"
7212 "Connection: keep-alive\r\n\r\n"),
7213 MockWrite(
7214 "GET / HTTP/1.1\r\n"
7215 "Host: www.example.org\r\n"
7216 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007217 };
7218
7219 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:427220 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7221 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:007222
[email protected]8ddf8322012-02-23 18:08:067223 SSLSocketDataProvider ssl(ASYNC, OK);
7224 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077225 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7226 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:007227
Ryan Sleevib8d7ea02018-05-07 20:01:017228 StaticSocketDataProvider data(data_reads, data_writes);
7229 StaticSocketDataProvider data2(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:077230 session_deps_.socket_factory->AddSocketDataProvider(&data);
7231 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:007232
[email protected]49639fa2011-12-20 23:22:417233 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007234
danakj1fd259a02016-04-16 03:17:097235 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:587236 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197237 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007238
tfarina42834112016-09-22 13:38:207239 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007240
robpercival214763f2016-07-01 23:27:017241 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7242 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007243
7244 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527245 ASSERT_TRUE(response);
7246 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007247 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7248
[email protected]90499482013-06-01 00:39:507249 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007250
7251 std::string response_data;
7252 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017253 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007254 EXPECT_EQ("hello world", response_data);
7255
7256 // Empty the current queue. This is necessary because idle sockets are
7257 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557258 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007259
7260 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507261 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007262
7263 // Now start the second transaction, which should reuse the previous socket.
7264
bnc87dcefc2017-05-25 12:47:587265 trans =
Jeremy Roman0579ed62017-08-29 15:56:197266 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007267
tfarina42834112016-09-22 13:38:207268 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007269
robpercival214763f2016-07-01 23:27:017270 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7271 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007272
7273 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:527274 ASSERT_TRUE(response);
7275 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:007276 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7277
[email protected]90499482013-06-01 00:39:507278 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007279
7280 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:017281 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:007282 EXPECT_EQ("hello world", response_data);
7283
7284 // Empty the current queue. This is necessary because idle sockets are
7285 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557286 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:007287
7288 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507289 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:007290}
7291
maksim.sisov0adf8592016-07-15 06:25:567292// Grab a socket, use it, and put it back into the pool. Then, make
7293// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017294TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567295 HttpRequestInfo request;
7296 request.method = "GET";
7297 request.url = GURL("http://www.example.org/");
7298 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107299 request.traffic_annotation =
7300 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567301
7302 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7303
bnc691fda62016-08-12 00:43:167304 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567305
7306 MockRead data_reads[] = {
7307 // A part of the response body is received with the response headers.
7308 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7309 // The rest of the response body is received in two parts.
7310 MockRead("lo"), MockRead(" world"),
7311 MockRead("junk"), // Should not be read!!
7312 MockRead(SYNCHRONOUS, OK),
7313 };
7314
Ryan Sleevib8d7ea02018-05-07 20:01:017315 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
maksim.sisov0adf8592016-07-15 06:25:567316 session_deps_.socket_factory->AddSocketDataProvider(&data);
7317
7318 TestCompletionCallback callback;
7319
tfarina42834112016-09-22 13:38:207320 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567321 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7322
7323 EXPECT_THAT(callback.GetResult(rv), IsOk());
7324
bnc691fda62016-08-12 00:43:167325 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567326 ASSERT_TRUE(response);
7327 EXPECT_TRUE(response->headers);
7328 std::string status_line = response->headers->GetStatusLine();
7329 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7330
7331 // Make memory critical notification and ensure the transaction still has been
7332 // operating right.
7333 base::MemoryPressureListener::NotifyMemoryPressure(
7334 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7335 base::RunLoop().RunUntilIdle();
7336
7337 // Socket should not be flushed as long as it is not idle.
7338 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7339
7340 std::string response_data;
bnc691fda62016-08-12 00:43:167341 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567342 EXPECT_THAT(rv, IsOk());
7343 EXPECT_EQ("hello world", response_data);
7344
7345 // Empty the current queue. This is necessary because idle sockets are
7346 // added to the connection pool asynchronously with a PostTask.
7347 base::RunLoop().RunUntilIdle();
7348
7349 // We now check to make sure the socket was added back to the pool.
7350 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7351
7352 // Idle sockets should be flushed now.
7353 base::MemoryPressureListener::NotifyMemoryPressure(
7354 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7355 base::RunLoop().RunUntilIdle();
7356
7357 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7358}
7359
yucliu48f235d2018-01-11 00:59:557360// Disable idle socket closing on memory pressure.
7361// Grab a socket, use it, and put it back into the pool. Then, make
7362// low memory notification and ensure the socket pool is NOT flushed.
7363TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
7364 HttpRequestInfo request;
7365 request.method = "GET";
7366 request.url = GURL("http://www.example.org/");
7367 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107368 request.traffic_annotation =
7369 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:557370
7371 // Disable idle socket closing on memory pressure.
7372 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
7373 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7374
7375 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7376
7377 MockRead data_reads[] = {
7378 // A part of the response body is received with the response headers.
7379 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7380 // The rest of the response body is received in two parts.
7381 MockRead("lo"), MockRead(" world"),
7382 MockRead("junk"), // Should not be read!!
7383 MockRead(SYNCHRONOUS, OK),
7384 };
7385
Ryan Sleevib8d7ea02018-05-07 20:01:017386 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
yucliu48f235d2018-01-11 00:59:557387 session_deps_.socket_factory->AddSocketDataProvider(&data);
7388
7389 TestCompletionCallback callback;
7390
7391 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
7392 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7393
7394 EXPECT_THAT(callback.GetResult(rv), IsOk());
7395
7396 const HttpResponseInfo* response = trans.GetResponseInfo();
7397 ASSERT_TRUE(response);
7398 EXPECT_TRUE(response->headers);
7399 std::string status_line = response->headers->GetStatusLine();
7400 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7401
7402 // Make memory critical notification and ensure the transaction still has been
7403 // operating right.
7404 base::MemoryPressureListener::NotifyMemoryPressure(
7405 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7406 base::RunLoop().RunUntilIdle();
7407
7408 // Socket should not be flushed as long as it is not idle.
7409 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
7410
7411 std::string response_data;
7412 rv = ReadTransaction(&trans, &response_data);
7413 EXPECT_THAT(rv, IsOk());
7414 EXPECT_EQ("hello world", response_data);
7415
7416 // Empty the current queue. This is necessary because idle sockets are
7417 // added to the connection pool asynchronously with a PostTask.
7418 base::RunLoop().RunUntilIdle();
7419
7420 // We now check to make sure the socket was added back to the pool.
7421 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7422
7423 // Idle sockets should NOT be flushed on moderate memory pressure.
7424 base::MemoryPressureListener::NotifyMemoryPressure(
7425 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
7426 base::RunLoop().RunUntilIdle();
7427
7428 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7429
7430 // Idle sockets should NOT be flushed on critical memory pressure.
7431 base::MemoryPressureListener::NotifyMemoryPressure(
7432 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7433 base::RunLoop().RunUntilIdle();
7434
7435 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
7436}
7437
maksim.sisov0adf8592016-07-15 06:25:567438// Grab an SSL socket, use it, and put it back into the pool. Then, make
7439// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:017440TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:567441 HttpRequestInfo request;
7442 request.method = "GET";
7443 request.url = GURL("https://www.example.org/");
7444 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107445 request.traffic_annotation =
7446 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:567447
7448 MockWrite data_writes[] = {
7449 MockWrite("GET / HTTP/1.1\r\n"
7450 "Host: www.example.org\r\n"
7451 "Connection: keep-alive\r\n\r\n"),
7452 };
7453
7454 MockRead data_reads[] = {
7455 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
7456 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
7457
7458 SSLSocketDataProvider ssl(ASYNC, OK);
7459 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
7460
Ryan Sleevib8d7ea02018-05-07 20:01:017461 StaticSocketDataProvider data(data_reads, data_writes);
maksim.sisov0adf8592016-07-15 06:25:567462 session_deps_.socket_factory->AddSocketDataProvider(&data);
7463
7464 TestCompletionCallback callback;
7465
7466 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167467 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:567468
7469 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
tfarina42834112016-09-22 13:38:207470 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:567471
7472 EXPECT_THAT(callback.GetResult(rv), IsOk());
7473
bnc691fda62016-08-12 00:43:167474 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:567475 ASSERT_TRUE(response);
7476 ASSERT_TRUE(response->headers);
7477 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7478
7479 // Make memory critical notification and ensure the transaction still has been
7480 // operating right.
7481 base::MemoryPressureListener::NotifyMemoryPressure(
7482 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7483 base::RunLoop().RunUntilIdle();
7484
7485 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7486
7487 std::string response_data;
bnc691fda62016-08-12 00:43:167488 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:567489 EXPECT_THAT(rv, IsOk());
7490 EXPECT_EQ("hello world", response_data);
7491
7492 // Empty the current queue. This is necessary because idle sockets are
7493 // added to the connection pool asynchronously with a PostTask.
7494 base::RunLoop().RunUntilIdle();
7495
7496 // We now check to make sure the socket was added back to the pool.
7497 EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
7498
7499 // Make memory notification once again and ensure idle socket is closed.
7500 base::MemoryPressureListener::NotifyMemoryPressure(
7501 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
7502 base::RunLoop().RunUntilIdle();
7503
7504 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
7505}
7506
[email protected]b4404c02009-04-10 16:38:527507// Make sure that we recycle a socket after a zero-length response.
7508// http://crbug.com/9880
bncd16676a2016-07-20 16:23:017509TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:427510 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:527511 request.method = "GET";
bncce36dca22015-04-21 22:11:237512 request.url = GURL(
7513 "http://www.example.org/csi?v=3&s=web&action=&"
7514 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
7515 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
7516 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e2018-02-07 07:41:107517 request.traffic_annotation =
7518 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:527519
danakj1fd259a02016-04-16 03:17:097520 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277521
[email protected]b4404c02009-04-10 16:38:527522 MockRead data_reads[] = {
7523 MockRead("HTTP/1.1 204 No Content\r\n"
7524 "Content-Length: 0\r\n"
7525 "Content-Type: text/html\r\n\r\n"),
7526 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067527 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:527528 };
7529
Ryan Sleevib8d7ea02018-05-07 20:01:017530 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077531 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:527532
mmenkecc2298e2015-12-07 18:20:187533 // Transaction must be created after the MockReads, so it's destroyed before
7534 // them.
bnc691fda62016-08-12 00:43:167535 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:187536
[email protected]49639fa2011-12-20 23:22:417537 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:527538
tfarina42834112016-09-22 13:38:207539 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017540 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:527541
7542 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017543 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527544
bnc691fda62016-08-12 00:43:167545 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527546 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:527547
wezca1070932016-05-26 20:30:527548 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:527549 std::string status_line = response->headers->GetStatusLine();
7550 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
7551
[email protected]90499482013-06-01 00:39:507552 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527553
7554 std::string response_data;
bnc691fda62016-08-12 00:43:167555 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017556 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:527557 EXPECT_EQ("", response_data);
7558
7559 // Empty the current queue. This is necessary because idle sockets are
7560 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557561 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527562
7563 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507564 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:527565}
7566
bncd16676a2016-07-20 16:23:017567TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:097568 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:227569 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:197570 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:227571 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:277572
[email protected]1c773ea12009-04-28 19:58:427573 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:517574 // Transaction 1: a GET request that succeeds. The socket is recycled
7575 // after use.
7576 request[0].method = "GET";
7577 request[0].url = GURL("http://www.google.com/");
7578 request[0].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107579 request[0].traffic_annotation =
7580 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517581 // Transaction 2: a POST request. Reuses the socket kept alive from
7582 // transaction 1. The first attempts fails when writing the POST data.
7583 // This causes the transaction to retry with a new socket. The second
7584 // attempt succeeds.
7585 request[1].method = "POST";
7586 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:277587 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:517588 request[1].load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:107589 request[1].traffic_annotation =
7590 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:517591
danakj1fd259a02016-04-16 03:17:097592 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:517593
7594 // The first socket is used for transaction 1 and the first attempt of
7595 // transaction 2.
7596
7597 // The response of transaction 1.
7598 MockRead data_reads1[] = {
7599 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
7600 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067601 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517602 };
7603 // The mock write results of transaction 1 and the first attempt of
7604 // transaction 2.
7605 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:067606 MockWrite(SYNCHRONOUS, 64), // GET
7607 MockWrite(SYNCHRONOUS, 93), // POST
7608 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:517609 };
Ryan Sleevib8d7ea02018-05-07 20:01:017610 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]372d34a2008-11-05 21:30:517611
7612 // The second socket is used for the second attempt of transaction 2.
7613
7614 // The response of transaction 2.
7615 MockRead data_reads2[] = {
7616 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
7617 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:067618 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:517619 };
7620 // The mock write results of the second attempt of transaction 2.
7621 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:067622 MockWrite(SYNCHRONOUS, 93), // POST
7623 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:517624 };
Ryan Sleevib8d7ea02018-05-07 20:01:017625 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]372d34a2008-11-05 21:30:517626
[email protected]bb88e1d32013-05-03 23:11:077627 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7628 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:517629
thestig9d3bb0c2015-01-24 00:49:517630 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:517631 "hello world", "welcome"
7632 };
7633
7634 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:167635 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:517636
[email protected]49639fa2011-12-20 23:22:417637 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:517638
tfarina42834112016-09-22 13:38:207639 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017640 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:517641
7642 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017643 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517644
bnc691fda62016-08-12 00:43:167645 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527646 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:517647
wezca1070932016-05-26 20:30:527648 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:517649 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
7650
7651 std::string response_data;
bnc691fda62016-08-12 00:43:167652 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017653 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:517654 EXPECT_EQ(kExpectedResponseData[i], response_data);
7655 }
7656}
[email protected]f9ee6b52008-11-08 06:46:237657
7658// Test the request-challenge-retry sequence for basic auth when there is
7659// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:167660// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:017661TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:427662 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237663 request.method = "GET";
bncce36dca22015-04-21 22:11:237664 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:417665 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:107666 request.traffic_annotation =
7667 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:297668
danakj1fd259a02016-04-16 03:17:097669 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167670 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277671
[email protected]a97cca42009-08-14 01:00:297672 // The password contains an escaped character -- for this test to pass it
7673 // will need to be unescaped by HttpNetworkTransaction.
7674 EXPECT_EQ("b%40r", request.url.password());
7675
[email protected]f9ee6b52008-11-08 06:46:237676 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237677 MockWrite(
7678 "GET / HTTP/1.1\r\n"
7679 "Host: www.example.org\r\n"
7680 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237681 };
7682
7683 MockRead data_reads1[] = {
7684 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7685 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7686 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067687 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237688 };
7689
[email protected]2262e3a2012-05-22 16:08:167690 // After the challenge above, the transaction will be restarted using the
7691 // identity from the url (foo, b@r) to answer the challenge.
7692 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237693 MockWrite(
7694 "GET / HTTP/1.1\r\n"
7695 "Host: www.example.org\r\n"
7696 "Connection: keep-alive\r\n"
7697 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167698 };
7699
7700 MockRead data_reads2[] = {
7701 MockRead("HTTP/1.0 200 OK\r\n"),
7702 MockRead("Content-Length: 100\r\n\r\n"),
7703 MockRead(SYNCHRONOUS, OK),
7704 };
7705
Ryan Sleevib8d7ea02018-05-07 20:01:017706 StaticSocketDataProvider data1(data_reads1, data_writes1);
7707 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:077708 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7709 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237710
[email protected]49639fa2011-12-20 23:22:417711 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207712 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017713 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237714 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017715 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167716 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167717
7718 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167719 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017720 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167721 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017722 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167723 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227724
bnc691fda62016-08-12 00:43:167725 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527726 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167727
7728 // There is no challenge info, since the identity in URL worked.
wezca1070932016-05-26 20:30:527729 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167730
7731 EXPECT_EQ(100, response->headers->GetContentLength());
7732
7733 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557734 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:167735}
7736
7737// Test the request-challenge-retry sequence for basic auth when there is an
7738// incorrect identity in the URL. The identity from the URL should be used only
7739// once.
bncd16676a2016-07-20 16:23:017740TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:167741 HttpRequestInfo request;
7742 request.method = "GET";
7743 // Note: the URL has a username:password in it. The password "baz" is
7744 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:237745 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:167746
7747 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:107748 request.traffic_annotation =
7749 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:167750
danakj1fd259a02016-04-16 03:17:097751 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167752 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:167753
7754 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237755 MockWrite(
7756 "GET / HTTP/1.1\r\n"
7757 "Host: www.example.org\r\n"
7758 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167759 };
7760
7761 MockRead data_reads1[] = {
7762 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7763 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7764 MockRead("Content-Length: 10\r\n\r\n"),
7765 MockRead(SYNCHRONOUS, ERR_FAILED),
7766 };
7767
7768 // After the challenge above, the transaction will be restarted using the
7769 // identity from the url (foo, baz) to answer the challenge.
7770 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237771 MockWrite(
7772 "GET / HTTP/1.1\r\n"
7773 "Host: www.example.org\r\n"
7774 "Connection: keep-alive\r\n"
7775 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167776 };
7777
7778 MockRead data_reads2[] = {
7779 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7780 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7781 MockRead("Content-Length: 10\r\n\r\n"),
7782 MockRead(SYNCHRONOUS, ERR_FAILED),
7783 };
7784
7785 // After the challenge above, the transaction will be restarted using the
7786 // identity supplied by the user (foo, bar) to answer the challenge.
7787 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237788 MockWrite(
7789 "GET / HTTP/1.1\r\n"
7790 "Host: www.example.org\r\n"
7791 "Connection: keep-alive\r\n"
7792 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:167793 };
7794
7795 MockRead data_reads3[] = {
7796 MockRead("HTTP/1.0 200 OK\r\n"),
7797 MockRead("Content-Length: 100\r\n\r\n"),
7798 MockRead(SYNCHRONOUS, OK),
7799 };
7800
Ryan Sleevib8d7ea02018-05-07 20:01:017801 StaticSocketDataProvider data1(data_reads1, data_writes1);
7802 StaticSocketDataProvider data2(data_reads2, data_writes2);
7803 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077804 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7805 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7806 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:167807
7808 TestCompletionCallback callback1;
7809
tfarina42834112016-09-22 13:38:207810 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017811 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167812
7813 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017814 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:167815
bnc691fda62016-08-12 00:43:167816 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167817 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:167818 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:017819 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167820 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017821 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167822 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167823
bnc691fda62016-08-12 00:43:167824 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527825 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167826 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7827
7828 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167829 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017830 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:167831 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017832 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167833 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:167834
bnc691fda62016-08-12 00:43:167835 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527836 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:167837
7838 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527839 EXPECT_FALSE(response->auth_challenge);
[email protected]2262e3a2012-05-22 16:08:167840
7841 EXPECT_EQ(100, response->headers->GetContentLength());
7842
[email protected]ea9dc9a2009-09-05 00:43:327843 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557844 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:327845}
7846
[email protected]2217aa22013-10-11 03:03:547847
7848// Test the request-challenge-retry sequence for basic auth when there is a
7849// correct identity in the URL, but its use is being suppressed. The identity
7850// from the URL should never be used.
bncd16676a2016-07-20 16:23:017851TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:547852 HttpRequestInfo request;
7853 request.method = "GET";
bncce36dca22015-04-21 22:11:237854 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:547855 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e2018-02-07 07:41:107856 request.traffic_annotation =
7857 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547858
danakj1fd259a02016-04-16 03:17:097859 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167860 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:547861
7862 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237863 MockWrite(
7864 "GET / HTTP/1.1\r\n"
7865 "Host: www.example.org\r\n"
7866 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547867 };
7868
7869 MockRead data_reads1[] = {
7870 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7871 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7872 MockRead("Content-Length: 10\r\n\r\n"),
7873 MockRead(SYNCHRONOUS, ERR_FAILED),
7874 };
7875
7876 // After the challenge above, the transaction will be restarted using the
7877 // identity supplied by the user, not the one in the URL, to answer the
7878 // challenge.
7879 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237880 MockWrite(
7881 "GET / HTTP/1.1\r\n"
7882 "Host: www.example.org\r\n"
7883 "Connection: keep-alive\r\n"
7884 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:547885 };
7886
7887 MockRead data_reads3[] = {
7888 MockRead("HTTP/1.0 200 OK\r\n"),
7889 MockRead("Content-Length: 100\r\n\r\n"),
7890 MockRead(SYNCHRONOUS, OK),
7891 };
7892
Ryan Sleevib8d7ea02018-05-07 20:01:017893 StaticSocketDataProvider data1(data_reads1, data_writes1);
7894 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]2217aa22013-10-11 03:03:547895 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7896 session_deps_.socket_factory->AddSocketDataProvider(&data3);
7897
7898 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:207899 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017900 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547901 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017902 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167903 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547904
bnc691fda62016-08-12 00:43:167905 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527906 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547907 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
7908
7909 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167910 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:017911 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:547912 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017913 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167914 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:547915
bnc691fda62016-08-12 00:43:167916 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527917 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:547918
7919 // There is no challenge info, since the identity worked.
wezca1070932016-05-26 20:30:527920 EXPECT_FALSE(response->auth_challenge);
[email protected]2217aa22013-10-11 03:03:547921 EXPECT_EQ(100, response->headers->GetContentLength());
7922
7923 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:557924 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:547925}
7926
[email protected]f9ee6b52008-11-08 06:46:237927// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:017928TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:097929 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:237930
7931 // Transaction 1: authenticate (foo, bar) on MyRealm1
7932 {
[email protected]1c773ea12009-04-28 19:58:427933 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:237934 request.method = "GET";
bncce36dca22015-04-21 22:11:237935 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:107936 request.traffic_annotation =
7937 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:237938
bnc691fda62016-08-12 00:43:167939 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277940
[email protected]f9ee6b52008-11-08 06:46:237941 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237942 MockWrite(
7943 "GET /x/y/z HTTP/1.1\r\n"
7944 "Host: www.example.org\r\n"
7945 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237946 };
7947
7948 MockRead data_reads1[] = {
7949 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7950 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7951 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067952 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:237953 };
7954
7955 // Resend with authorization (username=foo, password=bar)
7956 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237957 MockWrite(
7958 "GET /x/y/z HTTP/1.1\r\n"
7959 "Host: www.example.org\r\n"
7960 "Connection: keep-alive\r\n"
7961 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237962 };
7963
7964 // Sever accepts the authorization.
7965 MockRead data_reads2[] = {
7966 MockRead("HTTP/1.0 200 OK\r\n"),
7967 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067968 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:237969 };
7970
Ryan Sleevib8d7ea02018-05-07 20:01:017971 StaticSocketDataProvider data1(data_reads1, data_writes1);
7972 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:077973 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7974 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:237975
[email protected]49639fa2011-12-20 23:22:417976 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:237977
tfarina42834112016-09-22 13:38:207978 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017979 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237980
7981 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017982 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237983
bnc691fda62016-08-12 00:43:167984 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527985 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:047986 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:237987
[email protected]49639fa2011-12-20 23:22:417988 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:237989
bnc691fda62016-08-12 00:43:167990 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
7991 callback2.callback());
robpercival214763f2016-07-01 23:27:017992 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:237993
7994 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017995 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:237996
bnc691fda62016-08-12 00:43:167997 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527998 ASSERT_TRUE(response);
7999 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238000 EXPECT_EQ(100, response->headers->GetContentLength());
8001 }
8002
8003 // ------------------------------------------------------------------------
8004
8005 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
8006 {
[email protected]1c773ea12009-04-28 19:58:428007 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238008 request.method = "GET";
8009 // Note that Transaction 1 was at /x/y/z, so this is in the same
8010 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:238011 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:108012 request.traffic_annotation =
8013 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238014
bnc691fda62016-08-12 00:43:168015 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278016
[email protected]f9ee6b52008-11-08 06:46:238017 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238018 MockWrite(
8019 "GET /x/y/a/b HTTP/1.1\r\n"
8020 "Host: www.example.org\r\n"
8021 "Connection: keep-alive\r\n"
8022 // Send preemptive authorization for MyRealm1
8023 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238024 };
8025
8026 // The server didn't like the preemptive authorization, and
8027 // challenges us for a different realm (MyRealm2).
8028 MockRead data_reads1[] = {
8029 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8030 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
8031 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068032 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238033 };
8034
8035 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
8036 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238037 MockWrite(
8038 "GET /x/y/a/b HTTP/1.1\r\n"
8039 "Host: www.example.org\r\n"
8040 "Connection: keep-alive\r\n"
8041 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238042 };
8043
8044 // Sever accepts the authorization.
8045 MockRead data_reads2[] = {
8046 MockRead("HTTP/1.0 200 OK\r\n"),
8047 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068048 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238049 };
8050
Ryan Sleevib8d7ea02018-05-07 20:01:018051 StaticSocketDataProvider data1(data_reads1, data_writes1);
8052 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078053 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8054 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238055
[email protected]49639fa2011-12-20 23:22:418056 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238057
tfarina42834112016-09-22 13:38:208058 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018059 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238060
8061 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018062 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238063
bnc691fda62016-08-12 00:43:168064 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528065 ASSERT_TRUE(response);
8066 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048067 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438068 EXPECT_EQ("http://www.example.org",
8069 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048070 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198071 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238072
[email protected]49639fa2011-12-20 23:22:418073 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238074
bnc691fda62016-08-12 00:43:168075 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8076 callback2.callback());
robpercival214763f2016-07-01 23:27:018077 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238078
8079 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018080 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238081
bnc691fda62016-08-12 00:43:168082 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528083 ASSERT_TRUE(response);
8084 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238085 EXPECT_EQ(100, response->headers->GetContentLength());
8086 }
8087
8088 // ------------------------------------------------------------------------
8089
8090 // Transaction 3: Resend a request in MyRealm's protection space --
8091 // succeed with preemptive authorization.
8092 {
[email protected]1c773ea12009-04-28 19:58:428093 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238094 request.method = "GET";
bncce36dca22015-04-21 22:11:238095 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e2018-02-07 07:41:108096 request.traffic_annotation =
8097 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238098
bnc691fda62016-08-12 00:43:168099 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278100
[email protected]f9ee6b52008-11-08 06:46:238101 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238102 MockWrite(
8103 "GET /x/y/z2 HTTP/1.1\r\n"
8104 "Host: www.example.org\r\n"
8105 "Connection: keep-alive\r\n"
8106 // The authorization for MyRealm1 gets sent preemptively
8107 // (since the url is in the same protection space)
8108 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238109 };
8110
8111 // Sever accepts the preemptive authorization
8112 MockRead data_reads1[] = {
8113 MockRead("HTTP/1.0 200 OK\r\n"),
8114 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068115 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238116 };
8117
Ryan Sleevib8d7ea02018-05-07 20:01:018118 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:078119 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238120
[email protected]49639fa2011-12-20 23:22:418121 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238122
tfarina42834112016-09-22 13:38:208123 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018124 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238125
8126 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018127 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238128
bnc691fda62016-08-12 00:43:168129 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528130 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238131
wezca1070932016-05-26 20:30:528132 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238133 EXPECT_EQ(100, response->headers->GetContentLength());
8134 }
8135
8136 // ------------------------------------------------------------------------
8137
8138 // Transaction 4: request another URL in MyRealm (however the
8139 // url is not known to belong to the protection space, so no pre-auth).
8140 {
[email protected]1c773ea12009-04-28 19:58:428141 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238142 request.method = "GET";
bncce36dca22015-04-21 22:11:238143 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e2018-02-07 07:41:108144 request.traffic_annotation =
8145 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238146
bnc691fda62016-08-12 00:43:168147 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278148
[email protected]f9ee6b52008-11-08 06:46:238149 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238150 MockWrite(
8151 "GET /x/1 HTTP/1.1\r\n"
8152 "Host: www.example.org\r\n"
8153 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238154 };
8155
8156 MockRead data_reads1[] = {
8157 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8158 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8159 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068160 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238161 };
8162
8163 // Resend with authorization from MyRealm's cache.
8164 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238165 MockWrite(
8166 "GET /x/1 HTTP/1.1\r\n"
8167 "Host: www.example.org\r\n"
8168 "Connection: keep-alive\r\n"
8169 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238170 };
8171
8172 // Sever accepts the authorization.
8173 MockRead data_reads2[] = {
8174 MockRead("HTTP/1.0 200 OK\r\n"),
8175 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068176 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238177 };
8178
Ryan Sleevib8d7ea02018-05-07 20:01:018179 StaticSocketDataProvider data1(data_reads1, data_writes1);
8180 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078181 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8182 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238183
[email protected]49639fa2011-12-20 23:22:418184 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238185
tfarina42834112016-09-22 13:38:208186 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018187 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238188
8189 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018190 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238191
bnc691fda62016-08-12 00:43:168192 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418193 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168194 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018195 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228196 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018197 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168198 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228199
bnc691fda62016-08-12 00:43:168200 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528201 ASSERT_TRUE(response);
8202 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238203 EXPECT_EQ(100, response->headers->GetContentLength());
8204 }
8205
8206 // ------------------------------------------------------------------------
8207
8208 // Transaction 5: request a URL in MyRealm, but the server rejects the
8209 // cached identity. Should invalidate and re-prompt.
8210 {
[email protected]1c773ea12009-04-28 19:58:428211 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238212 request.method = "GET";
bncce36dca22015-04-21 22:11:238213 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e2018-02-07 07:41:108214 request.traffic_annotation =
8215 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238216
bnc691fda62016-08-12 00:43:168217 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278218
[email protected]f9ee6b52008-11-08 06:46:238219 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238220 MockWrite(
8221 "GET /p/q/t HTTP/1.1\r\n"
8222 "Host: www.example.org\r\n"
8223 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238224 };
8225
8226 MockRead data_reads1[] = {
8227 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8228 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8229 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068230 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238231 };
8232
8233 // Resend with authorization from cache for MyRealm.
8234 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238235 MockWrite(
8236 "GET /p/q/t HTTP/1.1\r\n"
8237 "Host: www.example.org\r\n"
8238 "Connection: keep-alive\r\n"
8239 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238240 };
8241
8242 // Sever rejects the authorization.
8243 MockRead data_reads2[] = {
8244 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8245 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8246 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068247 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238248 };
8249
8250 // At this point we should prompt for new credentials for MyRealm.
8251 // Restart with username=foo3, password=foo4.
8252 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238253 MockWrite(
8254 "GET /p/q/t HTTP/1.1\r\n"
8255 "Host: www.example.org\r\n"
8256 "Connection: keep-alive\r\n"
8257 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238258 };
8259
8260 // Sever accepts the authorization.
8261 MockRead data_reads3[] = {
8262 MockRead("HTTP/1.0 200 OK\r\n"),
8263 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068264 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238265 };
8266
Ryan Sleevib8d7ea02018-05-07 20:01:018267 StaticSocketDataProvider data1(data_reads1, data_writes1);
8268 StaticSocketDataProvider data2(data_reads2, data_writes2);
8269 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:078270 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8271 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8272 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:238273
[email protected]49639fa2011-12-20 23:22:418274 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238275
tfarina42834112016-09-22 13:38:208276 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018277 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238278
8279 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018280 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238281
bnc691fda62016-08-12 00:43:168282 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:418283 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168284 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018285 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:228286 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018287 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168288 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228289
bnc691fda62016-08-12 00:43:168290 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528291 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048292 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]f9ee6b52008-11-08 06:46:238293
[email protected]49639fa2011-12-20 23:22:418294 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:238295
bnc691fda62016-08-12 00:43:168296 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
8297 callback3.callback());
robpercival214763f2016-07-01 23:27:018298 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238299
[email protected]0757e7702009-03-27 04:00:228300 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018301 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238302
bnc691fda62016-08-12 00:43:168303 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528304 ASSERT_TRUE(response);
8305 EXPECT_FALSE(response->auth_challenge);
[email protected]f9ee6b52008-11-08 06:46:238306 EXPECT_EQ(100, response->headers->GetContentLength());
8307 }
8308}
[email protected]89ceba9a2009-03-21 03:46:068309
[email protected]3c32c5f2010-05-18 15:18:128310// Tests that nonce count increments when multiple auth attempts
8311// are started with the same nonce.
bncd16676a2016-07-20 16:23:018312TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:448313 HttpAuthHandlerDigest::Factory* digest_factory =
8314 new HttpAuthHandlerDigest::Factory();
8315 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
8316 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
8317 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:078318 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:098319 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:128320
8321 // Transaction 1: authenticate (foo, bar) on MyRealm1
8322 {
[email protected]3c32c5f2010-05-18 15:18:128323 HttpRequestInfo request;
8324 request.method = "GET";
bncce36dca22015-04-21 22:11:238325 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e2018-02-07 07:41:108326 request.traffic_annotation =
8327 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128328
bnc691fda62016-08-12 00:43:168329 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278330
[email protected]3c32c5f2010-05-18 15:18:128331 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238332 MockWrite(
8333 "GET /x/y/z HTTP/1.1\r\n"
8334 "Host: www.example.org\r\n"
8335 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128336 };
8337
8338 MockRead data_reads1[] = {
8339 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8340 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
8341 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068342 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128343 };
8344
8345 // Resend with authorization (username=foo, password=bar)
8346 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238347 MockWrite(
8348 "GET /x/y/z HTTP/1.1\r\n"
8349 "Host: www.example.org\r\n"
8350 "Connection: keep-alive\r\n"
8351 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8352 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
8353 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
8354 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128355 };
8356
8357 // Sever accepts the authorization.
8358 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:088359 MockRead("HTTP/1.0 200 OK\r\n"),
8360 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128361 };
8362
Ryan Sleevib8d7ea02018-05-07 20:01:018363 StaticSocketDataProvider data1(data_reads1, data_writes1);
8364 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078365 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8366 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:128367
[email protected]49639fa2011-12-20 23:22:418368 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128369
tfarina42834112016-09-22 13:38:208370 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018371 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128372
8373 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018374 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128375
bnc691fda62016-08-12 00:43:168376 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528377 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:048378 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
[email protected]3c32c5f2010-05-18 15:18:128379
[email protected]49639fa2011-12-20 23:22:418380 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:128381
bnc691fda62016-08-12 00:43:168382 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8383 callback2.callback());
robpercival214763f2016-07-01 23:27:018384 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128385
8386 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018387 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128388
bnc691fda62016-08-12 00:43:168389 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528390 ASSERT_TRUE(response);
8391 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128392 }
8393
8394 // ------------------------------------------------------------------------
8395
8396 // Transaction 2: Request another resource in digestive's protection space.
8397 // This will preemptively add an Authorization header which should have an
8398 // "nc" value of 2 (as compared to 1 in the first use.
8399 {
[email protected]3c32c5f2010-05-18 15:18:128400 HttpRequestInfo request;
8401 request.method = "GET";
8402 // Note that Transaction 1 was at /x/y/z, so this is in the same
8403 // protection space as digest.
bncce36dca22015-04-21 22:11:238404 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e2018-02-07 07:41:108405 request.traffic_annotation =
8406 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:128407
bnc691fda62016-08-12 00:43:168408 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278409
[email protected]3c32c5f2010-05-18 15:18:128410 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238411 MockWrite(
8412 "GET /x/y/a/b HTTP/1.1\r\n"
8413 "Host: www.example.org\r\n"
8414 "Connection: keep-alive\r\n"
8415 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
8416 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
8417 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
8418 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:128419 };
8420
8421 // Sever accepts the authorization.
8422 MockRead data_reads1[] = {
8423 MockRead("HTTP/1.0 200 OK\r\n"),
8424 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068425 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:128426 };
8427
Ryan Sleevib8d7ea02018-05-07 20:01:018428 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:078429 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:128430
[email protected]49639fa2011-12-20 23:22:418431 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:128432
tfarina42834112016-09-22 13:38:208433 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018434 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:128435
8436 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018437 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:128438
bnc691fda62016-08-12 00:43:168439 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528440 ASSERT_TRUE(response);
8441 EXPECT_FALSE(response->auth_challenge);
[email protected]3c32c5f2010-05-18 15:18:128442 }
8443}
8444
[email protected]89ceba9a2009-03-21 03:46:068445// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:018446TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:068447 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:098448 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168449 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:068450
8451 // Setup some state (which we expect ResetStateForRestart() will clear).
Victor Costan9c7302b2018-08-27 16:39:448452 trans.read_buf_ = base::MakeRefCounted<IOBuffer>(15);
bnc691fda62016-08-12 00:43:168453 trans.read_buf_len_ = 15;
8454 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:068455
8456 // Setup state in response_
bnc691fda62016-08-12 00:43:168457 HttpResponseInfo* response = &trans.response_;
[email protected]0877e3d2009-10-17 22:29:578458 response->auth_challenge = new AuthChallengeInfo();
[email protected]70d66502011-09-23 00:55:088459 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:578460 response->response_time = base::Time::Now();
8461 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:068462
8463 { // Setup state for response_.vary_data
8464 HttpRequestInfo request;
8465 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
8466 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:278467 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:438468 request.extra_headers.SetHeader("Foo", "1");
8469 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:508470 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:068471 }
8472
8473 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:168474 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:068475
8476 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:168477 EXPECT_FALSE(trans.read_buf_);
8478 EXPECT_EQ(0, trans.read_buf_len_);
8479 EXPECT_TRUE(trans.request_headers_.IsEmpty());
wezca1070932016-05-26 20:30:528480 EXPECT_FALSE(response->auth_challenge);
8481 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:048482 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:088483 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:578484 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:068485}
8486
[email protected]bacff652009-03-31 17:50:338487// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:018488TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:338489 HttpRequestInfo request;
8490 request.method = "GET";
bncce36dca22015-04-21 22:11:238491 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108492 request.traffic_annotation =
8493 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338494
danakj1fd259a02016-04-16 03:17:098495 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168496 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278497
[email protected]bacff652009-03-31 17:50:338498 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238499 MockWrite(
8500 "GET / HTTP/1.1\r\n"
8501 "Host: www.example.org\r\n"
8502 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338503 };
8504
8505 MockRead data_reads[] = {
8506 MockRead("HTTP/1.0 200 OK\r\n"),
8507 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8508 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068509 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338510 };
8511
[email protected]5ecc992a42009-11-11 01:41:598512 StaticSocketDataProvider ssl_bad_certificate;
Ryan Sleevib8d7ea02018-05-07 20:01:018513 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068514 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8515 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338516
[email protected]bb88e1d32013-05-03 23:11:078517 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8518 session_deps_.socket_factory->AddSocketDataProvider(&data);
8519 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8520 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338521
[email protected]49639fa2011-12-20 23:22:418522 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338523
tfarina42834112016-09-22 13:38:208524 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018525 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338526
8527 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018528 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338529
bnc691fda62016-08-12 00:43:168530 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018531 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338532
8533 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018534 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338535
bnc691fda62016-08-12 00:43:168536 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338537
wezca1070932016-05-26 20:30:528538 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338539 EXPECT_EQ(100, response->headers->GetContentLength());
8540}
8541
8542// Test HTTPS connections to a site with a bad certificate, going through a
8543// proxy
bncd16676a2016-07-20 16:23:018544TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498545 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8546 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338547
8548 HttpRequestInfo request;
8549 request.method = "GET";
bncce36dca22015-04-21 22:11:238550 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108551 request.traffic_annotation =
8552 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:338553
8554 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:178555 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8556 "Host: www.example.org:443\r\n"
8557 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338558 };
8559
8560 MockRead proxy_reads[] = {
8561 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068562 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:338563 };
8564
8565 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178566 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8567 "Host: www.example.org:443\r\n"
8568 "Proxy-Connection: keep-alive\r\n\r\n"),
8569 MockWrite("GET / HTTP/1.1\r\n"
8570 "Host: www.example.org\r\n"
8571 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:338572 };
8573
8574 MockRead data_reads[] = {
8575 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8576 MockRead("HTTP/1.0 200 OK\r\n"),
8577 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8578 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068579 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:338580 };
8581
Ryan Sleevib8d7ea02018-05-07 20:01:018582 StaticSocketDataProvider ssl_bad_certificate(proxy_reads, proxy_writes);
8583 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068584 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
8585 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:338586
[email protected]bb88e1d32013-05-03 23:11:078587 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
8588 session_deps_.socket_factory->AddSocketDataProvider(&data);
8589 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
8590 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:338591
[email protected]49639fa2011-12-20 23:22:418592 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:338593
8594 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:078595 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:338596
danakj1fd259a02016-04-16 03:17:098597 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168598 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:338599
tfarina42834112016-09-22 13:38:208600 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018601 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338602
8603 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018604 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:338605
bnc691fda62016-08-12 00:43:168606 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:018607 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:338608
8609 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018610 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:338611
bnc691fda62016-08-12 00:43:168612 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:338613
wezca1070932016-05-26 20:30:528614 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:338615 EXPECT_EQ(100, response->headers->GetContentLength());
8616 }
8617}
8618
[email protected]2df19bb2010-08-25 20:13:468619
8620// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:018621TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598622 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498623 ProxyResolutionService::CreateFixedFromPacResult(
8624 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518625 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078626 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:468627
8628 HttpRequestInfo request;
8629 request.method = "GET";
bncce36dca22015-04-21 22:11:238630 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108631 request.traffic_annotation =
8632 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:468633
8634 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178635 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8636 "Host: www.example.org:443\r\n"
8637 "Proxy-Connection: keep-alive\r\n\r\n"),
8638 MockWrite("GET / HTTP/1.1\r\n"
8639 "Host: www.example.org\r\n"
8640 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:468641 };
8642
8643 MockRead data_reads[] = {
8644 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
8645 MockRead("HTTP/1.1 200 OK\r\n"),
8646 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
8647 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068648 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:468649 };
8650
Ryan Sleevib8d7ea02018-05-07 20:01:018651 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068652 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
8653 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:468654
[email protected]bb88e1d32013-05-03 23:11:078655 session_deps_.socket_factory->AddSocketDataProvider(&data);
8656 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
8657 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:468658
[email protected]49639fa2011-12-20 23:22:418659 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:468660
danakj1fd259a02016-04-16 03:17:098661 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168662 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:468663
tfarina42834112016-09-22 13:38:208664 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018665 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:468666
8667 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018668 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168669 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:468670
wezca1070932016-05-26 20:30:528671 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:468672
tbansal2ecbbc72016-10-06 17:15:478673 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:468674 EXPECT_TRUE(response->headers->IsKeepAlive());
8675 EXPECT_EQ(200, response->headers->response_code());
8676 EXPECT_EQ(100, response->headers->GetContentLength());
8677 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:208678
8679 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168680 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208681 TestLoadTimingNotReusedWithPac(load_timing_info,
8682 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:468683}
8684
[email protected]511f6f52010-12-17 03:58:298685// Test an HTTPS Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018686TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:598687 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498688 ProxyResolutionService::CreateFixedFromPacResult(
8689 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518690 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:078691 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:298692
8693 HttpRequestInfo request;
8694 request.method = "GET";
bncce36dca22015-04-21 22:11:238695 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108696 request.traffic_annotation =
8697 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298698
8699 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178700 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8701 "Host: www.example.org:443\r\n"
8702 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298703 };
8704
8705 MockRead data_reads[] = {
8706 MockRead("HTTP/1.1 302 Redirect\r\n"),
8707 MockRead("Location: http://login.example.com/\r\n"),
8708 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068709 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298710 };
8711
Ryan Sleevib8d7ea02018-05-07 20:01:018712 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068713 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298714
[email protected]bb88e1d32013-05-03 23:11:078715 session_deps_.socket_factory->AddSocketDataProvider(&data);
8716 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298717
[email protected]49639fa2011-12-20 23:22:418718 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298719
danakj1fd259a02016-04-16 03:17:098720 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168721 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298722
tfarina42834112016-09-22 13:38:208723 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018724 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298725
8726 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018727 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168728 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298729
wezca1070932016-05-26 20:30:528730 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298731
8732 EXPECT_EQ(302, response->headers->response_code());
8733 std::string url;
8734 EXPECT_TRUE(response->headers->IsRedirect(&url));
8735 EXPECT_EQ("http://login.example.com/", url);
[email protected]029c83b62013-01-24 05:28:208736
8737 // In the case of redirects from proxies, HttpNetworkTransaction returns
8738 // timing for the proxy connection instead of the connection to the host,
8739 // and no send / receive times.
8740 // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
8741 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:168742 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:208743
8744 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:198745 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:208746
8747 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
8748 EXPECT_LE(load_timing_info.proxy_resolve_start,
8749 load_timing_info.proxy_resolve_end);
8750 EXPECT_LE(load_timing_info.proxy_resolve_end,
8751 load_timing_info.connect_timing.connect_start);
8752 ExpectConnectTimingHasTimes(
8753 load_timing_info.connect_timing,
8754 CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
8755
8756 EXPECT_TRUE(load_timing_info.send_start.is_null());
8757 EXPECT_TRUE(load_timing_info.send_end.is_null());
8758 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]511f6f52010-12-17 03:58:298759}
8760
8761// Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
bncd16676a2016-07-20 16:23:018762TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498763 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8764 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298765
8766 HttpRequestInfo request;
8767 request.method = "GET";
bncce36dca22015-04-21 22:11:238768 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108769 request.traffic_annotation =
8770 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298771
Ryan Hamilton0239aac2018-05-19 00:03:138772 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238773 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:138774 spdy::SpdySerializedFrame goaway(
8775 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298776 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418777 CreateMockWrite(conn, 0, SYNCHRONOUS),
8778 CreateMockWrite(goaway, 2, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:298779 };
8780
8781 static const char* const kExtraHeaders[] = {
8782 "location",
8783 "http://login.example.com/",
8784 };
Ryan Hamilton0239aac2018-05-19 00:03:138785 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238786 "302", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:298787 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418788 CreateMockRead(resp, 1), MockRead(ASYNC, 0, 3), // EOF
[email protected]511f6f52010-12-17 03:58:298789 };
8790
Ryan Sleevib8d7ea02018-05-07 20:01:018791 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068792 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368793 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298794
[email protected]bb88e1d32013-05-03 23:11:078795 session_deps_.socket_factory->AddSocketDataProvider(&data);
8796 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298797
[email protected]49639fa2011-12-20 23:22:418798 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298799
danakj1fd259a02016-04-16 03:17:098800 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168801 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298802
tfarina42834112016-09-22 13:38:208803 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018804 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298805
8806 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018807 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168808 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]511f6f52010-12-17 03:58:298809
wezca1070932016-05-26 20:30:528810 ASSERT_TRUE(response);
[email protected]511f6f52010-12-17 03:58:298811
8812 EXPECT_EQ(302, response->headers->response_code());
8813 std::string url;
8814 EXPECT_TRUE(response->headers->IsRedirect(&url));
8815 EXPECT_EQ("http://login.example.com/", url);
8816}
8817
[email protected]4eddbc732012-08-09 05:40:178818// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018819TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498820 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8821 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298822
8823 HttpRequestInfo request;
8824 request.method = "GET";
bncce36dca22015-04-21 22:11:238825 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108826 request.traffic_annotation =
8827 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298828
8829 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:178830 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
8831 "Host: www.example.org:443\r\n"
8832 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:298833 };
8834
8835 MockRead data_reads[] = {
8836 MockRead("HTTP/1.1 404 Not Found\r\n"),
8837 MockRead("Content-Length: 23\r\n\r\n"),
8838 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:068839 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:298840 };
8841
Ryan Sleevib8d7ea02018-05-07 20:01:018842 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068843 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:298844
[email protected]bb88e1d32013-05-03 23:11:078845 session_deps_.socket_factory->AddSocketDataProvider(&data);
8846 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298847
[email protected]49639fa2011-12-20 23:22:418848 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298849
danakj1fd259a02016-04-16 03:17:098850 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168851 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298852
tfarina42834112016-09-22 13:38:208853 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018854 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298855
8856 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018857 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298858
ttuttle960fcbf2016-04-19 13:26:328859 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298860}
8861
[email protected]4eddbc732012-08-09 05:40:178862// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:018863TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:498864 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
8865 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298866
8867 HttpRequestInfo request;
8868 request.method = "GET";
bncce36dca22015-04-21 22:11:238869 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:108870 request.traffic_annotation =
8871 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:298872
Ryan Hamilton0239aac2018-05-19 00:03:138873 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238874 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:138875 spdy::SpdySerializedFrame rst(
8876 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:298877 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:418878 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:298879 };
8880
8881 static const char* const kExtraHeaders[] = {
8882 "location",
8883 "http://login.example.com/",
8884 };
Ryan Hamilton0239aac2018-05-19 00:03:138885 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
bncc9f762a2016-12-06 20:38:238886 "404", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:138887 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:198888 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:298889 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:418890 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:138891 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:298892 };
8893
Ryan Sleevib8d7ea02018-05-07 20:01:018894 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:068895 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:368896 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:298897
[email protected]bb88e1d32013-05-03 23:11:078898 session_deps_.socket_factory->AddSocketDataProvider(&data);
8899 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:298900
[email protected]49639fa2011-12-20 23:22:418901 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:298902
danakj1fd259a02016-04-16 03:17:098903 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168904 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:298905
tfarina42834112016-09-22 13:38:208906 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018907 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:298908
8909 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018910 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:298911
ttuttle960fcbf2016-04-19 13:26:328912 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:298913}
8914
[email protected]0c5fb722012-02-28 11:50:358915// Test the request-challenge-retry sequence for basic auth, through
8916// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:018917TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:358918 HttpRequestInfo request;
8919 request.method = "GET";
bncce36dca22015-04-21 22:11:238920 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:358921 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:298922 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e2018-02-07 07:41:108923 request.traffic_annotation =
8924 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:358925
8926 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:598927 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:498928 ProxyResolutionService::CreateFixedFromPacResult(
8929 "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:518930 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:078931 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:098932 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:358933
8934 // Since we have proxy, should try to establish tunnel.
Ryan Hamilton0239aac2018-05-19 00:03:138935 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
bncce36dca22015-04-21 22:11:238936 NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:138937 spdy::SpdySerializedFrame rst(
8938 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:388939 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:358940
bnc691fda62016-08-12 00:43:168941 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:358942 // be issuing -- the final header line contains the credentials.
8943 const char* const kAuthCredentials[] = {
8944 "proxy-authorization", "Basic Zm9vOmJhcg==",
8945 };
Ryan Hamilton0239aac2018-05-19 00:03:138946 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
lgarrona91df87f2014-12-05 00:51:348947 kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
bncce36dca22015-04-21 22:11:238948 HostPortPair("www.example.org", 443)));
8949 // fetch https://www.example.org/ via HTTP
8950 const char get[] =
8951 "GET / HTTP/1.1\r\n"
8952 "Host: www.example.org\r\n"
8953 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:138954 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:198955 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:358956
8957 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:418958 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
8959 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:358960 };
8961
8962 // The proxy responds to the connect with a 407, using a persistent
8963 // connection.
thestig9d3bb0c2015-01-24 00:49:518964 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:358965 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:358966 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
8967 };
Ryan Hamilton0239aac2018-05-19 00:03:138968 spdy::SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
bncdf80d44fd2016-07-15 20:27:418969 kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:358970
Ryan Hamilton0239aac2018-05-19 00:03:138971 spdy::SpdySerializedFrame conn_resp(
8972 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
[email protected]0c5fb722012-02-28 11:50:358973 const char resp[] = "HTTP/1.1 200 OK\r\n"
8974 "Content-Length: 5\r\n\r\n";
8975
Ryan Hamilton0239aac2018-05-19 00:03:138976 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:198977 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:138978 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:198979 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:358980 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:418981 CreateMockRead(conn_auth_resp, 1, ASYNC),
8982 CreateMockRead(conn_resp, 4, ASYNC),
8983 CreateMockRead(wrapped_get_resp, 6, ASYNC),
8984 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:138985 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:358986 };
8987
Ryan Sleevib8d7ea02018-05-07 20:01:018988 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:078989 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:358990 // Negotiate SPDY to the proxy
8991 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:368992 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:078993 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:358994 // Vanilla SSL to the server
8995 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078996 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:358997
8998 TestCompletionCallback callback1;
8999
bnc87dcefc2017-05-25 12:47:589000 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199001 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:359002
9003 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019004 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359005
9006 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019007 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:469008 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:359009 log.GetEntries(&entries);
9010 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:009011 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
9012 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:359013 ExpectLogContainsSomewhere(
9014 entries, pos,
mikecirone8b85c432016-09-08 19:11:009015 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
9016 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:359017
9018 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529019 ASSERT_TRUE(response);
9020 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:359021 EXPECT_EQ(407, response->headers->response_code());
9022 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
wezca1070932016-05-26 20:30:529023 EXPECT_TRUE(response->auth_challenge);
asanka098c0092016-06-16 20:18:439024 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge.get()));
[email protected]0c5fb722012-02-28 11:50:359025
9026 TestCompletionCallback callback2;
9027
9028 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
9029 callback2.callback());
robpercival214763f2016-07-01 23:27:019030 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359031
9032 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019033 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:359034
9035 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529036 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:359037
9038 EXPECT_TRUE(response->headers->IsKeepAlive());
9039 EXPECT_EQ(200, response->headers->response_code());
9040 EXPECT_EQ(5, response->headers->GetContentLength());
9041 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9042
9043 // The password prompt info should not be set.
wezca1070932016-05-26 20:30:529044 EXPECT_FALSE(response->auth_challenge);
[email protected]0c5fb722012-02-28 11:50:359045
[email protected]029c83b62013-01-24 05:28:209046 LoadTimingInfo load_timing_info;
9047 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9048 TestLoadTimingNotReusedWithPac(load_timing_info,
9049 CONNECT_TIMING_HAS_SSL_TIMES);
9050
[email protected]0c5fb722012-02-28 11:50:359051 trans.reset();
9052 session->CloseAllConnections();
9053}
9054
[email protected]7c6f7ba2012-04-03 04:09:299055// Test that an explicitly trusted SPDY proxy can push a resource from an
9056// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:019057TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:159058 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199059 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159060 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9061 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:299062 HttpRequestInfo request;
9063 HttpRequestInfo push_request;
Ramin Halavatib5e433e2018-02-07 07:41:109064 request.traffic_annotation =
9065 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299066
[email protected]7c6f7ba2012-04-03 04:09:299067 request.method = "GET";
bncce36dca22015-04-21 22:11:239068 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:299069 push_request.method = "GET";
9070 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e2018-02-07 07:41:109071 push_request.traffic_annotation =
9072 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299073
tbansal28e68f82016-02-04 02:56:159074 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:599075 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499076 ProxyResolutionService::CreateFixedFromPacResult(
9077 "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519078 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079079 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509080
Eric Roman3d8546a2018-09-10 17:00:529081 session_deps_.proxy_resolution_service->SetProxyDelegate(
9082 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:509083
danakj1fd259a02016-04-16 03:17:099084 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:299085
Ryan Hamilton0239aac2018-05-19 00:03:139086 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459087 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:139088 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:359089 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:299090
9091 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419092 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359093 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:299094 };
9095
Ryan Hamilton0239aac2018-05-19 00:03:139096 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky7bf94362018-01-10 13:19:369097 NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
9098
Ryan Hamilton0239aac2018-05-19 00:03:139099 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159100 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:299101
Ryan Hamilton0239aac2018-05-19 00:03:139102 spdy::SpdySerializedFrame stream1_body(
9103 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:299104
Ryan Hamilton0239aac2018-05-19 00:03:139105 spdy::SpdySerializedFrame stream2_body(
Bence Békyd74f4382018-02-20 18:26:199106 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:299107
9108 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:369109 CreateMockRead(stream2_syn, 1, ASYNC),
9110 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359111 CreateMockRead(stream1_body, 4, ASYNC),
9112 CreateMockRead(stream2_body, 5, ASYNC),
9113 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:299114 };
9115
Ryan Sleevib8d7ea02018-05-07 20:01:019116 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:079117 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:299118 // Negotiate SPDY to the proxy
9119 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369120 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079121 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:299122
bnc87dcefc2017-05-25 12:47:589123 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199124 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:299125 TestCompletionCallback callback;
9126 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019127 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299128
9129 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019130 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299131 const HttpResponseInfo* response = trans->GetResponseInfo();
9132
bnc87dcefc2017-05-25 12:47:589133 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:199134 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:509135 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019136 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:299137
9138 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019139 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299140 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
9141
wezca1070932016-05-26 20:30:529142 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:299143 EXPECT_TRUE(response->headers->IsKeepAlive());
9144
9145 EXPECT_EQ(200, response->headers->response_code());
9146 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9147
9148 std::string response_data;
9149 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019150 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299151 EXPECT_EQ("hello!", response_data);
9152
[email protected]029c83b62013-01-24 05:28:209153 LoadTimingInfo load_timing_info;
9154 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9155 TestLoadTimingNotReusedWithPac(load_timing_info,
9156 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9157
[email protected]7c6f7ba2012-04-03 04:09:299158 // Verify the pushed stream.
wezca1070932016-05-26 20:30:529159 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:299160 EXPECT_EQ(200, push_response->headers->response_code());
9161
9162 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019163 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:299164 EXPECT_EQ("pushed", response_data);
9165
[email protected]029c83b62013-01-24 05:28:209166 LoadTimingInfo push_load_timing_info;
9167 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
9168 TestLoadTimingReusedWithPac(push_load_timing_info);
9169 // The transactions should share a socket ID, despite being for different
9170 // origins.
9171 EXPECT_EQ(load_timing_info.socket_log_id,
9172 push_load_timing_info.socket_log_id);
9173
[email protected]7c6f7ba2012-04-03 04:09:299174 trans.reset();
9175 push_trans.reset();
9176 session->CloseAllConnections();
9177}
9178
[email protected]8c843192012-04-05 07:15:009179// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:019180TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159181 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199182 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159183 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9184 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:009185 HttpRequestInfo request;
9186
9187 request.method = "GET";
bncce36dca22015-04-21 22:11:239188 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109189 request.traffic_annotation =
9190 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:009191
Ramin Halavatica8d5252018-03-12 05:33:499192 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9193 "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519194 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079195 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:509196
9197 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:529198 session_deps_.proxy_resolution_service->SetProxyDelegate(
9199 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:509200
danakj1fd259a02016-04-16 03:17:099201 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:009202
Ryan Hamilton0239aac2018-05-19 00:03:139203 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459204 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:009205
Ryan Hamilton0239aac2018-05-19 00:03:139206 spdy::SpdySerializedFrame push_rst(
9207 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:009208
9209 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419210 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:009211 };
9212
Ryan Hamilton0239aac2018-05-19 00:03:139213 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159214 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
[email protected]8c843192012-04-05 07:15:009215
Ryan Hamilton0239aac2018-05-19 00:03:139216 spdy::SpdySerializedFrame stream1_body(
9217 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:009218
Ryan Hamilton0239aac2018-05-19 00:03:139219 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
bncb03b1092016-04-06 11:19:559220 NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:009221
9222 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419223 CreateMockRead(stream1_reply, 1, ASYNC),
9224 CreateMockRead(stream2_syn, 2, ASYNC),
9225 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:599226 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:009227 };
9228
Ryan Sleevib8d7ea02018-05-07 20:01:019229 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:079230 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:009231 // Negotiate SPDY to the proxy
9232 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369233 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079234 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:009235
bnc87dcefc2017-05-25 12:47:589236 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199237 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:009238 TestCompletionCallback callback;
9239 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019240 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:009241
9242 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019243 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009244 const HttpResponseInfo* response = trans->GetResponseInfo();
9245
wezca1070932016-05-26 20:30:529246 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:009247 EXPECT_TRUE(response->headers->IsKeepAlive());
9248
9249 EXPECT_EQ(200, response->headers->response_code());
9250 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9251
9252 std::string response_data;
9253 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019254 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:009255 EXPECT_EQ("hello!", response_data);
9256
9257 trans.reset();
9258 session->CloseAllConnections();
9259}
9260
tbansal8ef1d3e2016-02-03 04:05:429261// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
9262// resources.
bncd16676a2016-07-20 16:23:019263TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:159264 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199265 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159266 proxy_delegate->set_trusted_spdy_proxy(
9267 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
9268
tbansal8ef1d3e2016-02-03 04:05:429269 HttpRequestInfo request;
9270
9271 request.method = "GET";
9272 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109273 request.traffic_annotation =
9274 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:429275
9276 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:499277 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9278 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:429279 BoundTestNetLog log;
9280 session_deps_.net_log = log.bound().net_log();
9281
9282 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:529283 session_deps_.proxy_resolution_service->SetProxyDelegate(
9284 proxy_delegate.get());
tbansal8ef1d3e2016-02-03 04:05:429285
danakj1fd259a02016-04-16 03:17:099286 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:429287
Ryan Hamilton0239aac2018-05-19 00:03:139288 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:459289 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:139290 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:359291 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:429292
9293 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419294 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:359295 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:429296 };
9297
Ryan Hamilton0239aac2018-05-19 00:03:139298 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:159299 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429300
Ryan Hamilton0239aac2018-05-19 00:03:139301 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:339302 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:499303
Ryan Hamilton0239aac2018-05-19 00:03:139304 spdy::SpdySerializedFrame stream1_body(
9305 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429306
Ryan Hamilton0239aac2018-05-19 00:03:139307 spdy::SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:159308 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:429309
Ryan Hamilton0239aac2018-05-19 00:03:139310 spdy::SpdySerializedFrame stream2_body(
9311 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:429312
9313 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419314 CreateMockRead(stream1_reply, 1, ASYNC),
9315 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:359316 CreateMockRead(stream1_body, 4, ASYNC),
9317 CreateMockRead(stream2_body, 5, ASYNC),
9318 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:429319 };
9320
Ryan Sleevib8d7ea02018-05-07 20:01:019321 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
tbansal8ef1d3e2016-02-03 04:05:429322 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
9323 // Negotiate SPDY to the proxy
9324 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369325 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:429326 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
9327
bnc87dcefc2017-05-25 12:47:589328 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199329 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:429330 TestCompletionCallback callback;
9331 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019332 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:429333
9334 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019335 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429336 const HttpResponseInfo* response = trans->GetResponseInfo();
9337
wezca1070932016-05-26 20:30:529338 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:429339 EXPECT_TRUE(response->headers->IsKeepAlive());
9340
9341 EXPECT_EQ(200, response->headers->response_code());
9342 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9343
9344 std::string response_data;
9345 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:019346 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:429347 EXPECT_EQ("hello!", response_data);
9348
9349 trans.reset();
9350 session->CloseAllConnections();
9351}
9352
[email protected]2df19bb2010-08-25 20:13:469353// Test HTTPS connections to a site with a bad certificate, going through an
9354// HTTPS proxy
bncd16676a2016-07-20 16:23:019355TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499356 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9357 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469358
9359 HttpRequestInfo request;
9360 request.method = "GET";
bncce36dca22015-04-21 22:11:239361 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109362 request.traffic_annotation =
9363 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469364
9365 // Attempt to fetch the URL from a server with a bad cert
9366 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:179367 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9368 "Host: www.example.org:443\r\n"
9369 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469370 };
9371
9372 MockRead bad_cert_reads[] = {
9373 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069374 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:469375 };
9376
9377 // Attempt to fetch the URL with a good cert
9378 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179379 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9380 "Host: www.example.org:443\r\n"
9381 "Proxy-Connection: keep-alive\r\n\r\n"),
9382 MockWrite("GET / HTTP/1.1\r\n"
9383 "Host: www.example.org\r\n"
9384 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469385 };
9386
9387 MockRead good_cert_reads[] = {
9388 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9389 MockRead("HTTP/1.0 200 OK\r\n"),
9390 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9391 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069392 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469393 };
9394
Ryan Sleevib8d7ea02018-05-07 20:01:019395 StaticSocketDataProvider ssl_bad_certificate(bad_cert_reads, bad_cert_writes);
9396 StaticSocketDataProvider data(good_cert_reads, good_data_writes);
[email protected]8ddf8322012-02-23 18:08:069397 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9398 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:469399
9400 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:079401 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9402 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9403 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:469404
9405 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:079406 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
9407 session_deps_.socket_factory->AddSocketDataProvider(&data);
9408 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:469409
[email protected]49639fa2011-12-20 23:22:419410 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469411
danakj1fd259a02016-04-16 03:17:099412 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169413 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469414
tfarina42834112016-09-22 13:38:209415 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019416 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469417
9418 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019419 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:469420
bnc691fda62016-08-12 00:43:169421 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019422 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469423
9424 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019425 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:469426
bnc691fda62016-08-12 00:43:169427 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469428
wezca1070932016-05-26 20:30:529429 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469430 EXPECT_EQ(100, response->headers->GetContentLength());
9431}
9432
bncd16676a2016-07-20 16:23:019433TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:429434 HttpRequestInfo request;
9435 request.method = "GET";
bncce36dca22015-04-21 22:11:239436 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439437 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9438 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e2018-02-07 07:41:109439 request.traffic_annotation =
9440 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429441
danakj1fd259a02016-04-16 03:17:099442 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169443 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279444
[email protected]1c773ea12009-04-28 19:58:429445 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239446 MockWrite(
9447 "GET / HTTP/1.1\r\n"
9448 "Host: www.example.org\r\n"
9449 "Connection: keep-alive\r\n"
9450 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429451 };
9452
9453 // Lastly, the server responds with the actual content.
9454 MockRead data_reads[] = {
9455 MockRead("HTTP/1.0 200 OK\r\n"),
9456 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9457 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069458 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429459 };
9460
Ryan Sleevib8d7ea02018-05-07 20:01:019461 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079462 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429463
[email protected]49639fa2011-12-20 23:22:419464 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429465
tfarina42834112016-09-22 13:38:209466 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429468
9469 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019470 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429471}
9472
bncd16676a2016-07-20 16:23:019473TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
[email protected]da81f132010-08-18 23:39:299474 HttpRequestInfo request;
9475 request.method = "GET";
bncce36dca22015-04-21 22:11:239476 request.url = GURL("https://www.example.org/");
[email protected]da81f132010-08-18 23:39:299477 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
9478 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e2018-02-07 07:41:109479 request.traffic_annotation =
9480 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]da81f132010-08-18 23:39:299481
Ramin Halavatica8d5252018-03-12 05:33:499482 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9483 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:099484 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169485 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279486
[email protected]da81f132010-08-18 23:39:299487 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179488 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9489 "Host: www.example.org:443\r\n"
9490 "Proxy-Connection: keep-alive\r\n"
9491 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]da81f132010-08-18 23:39:299492 };
9493 MockRead data_reads[] = {
9494 // Return an error, so the transaction stops here (this test isn't
9495 // interested in the rest).
9496 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
9497 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9498 MockRead("Proxy-Connection: close\r\n\r\n"),
9499 };
9500
Ryan Sleevib8d7ea02018-05-07 20:01:019501 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079502 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:299503
[email protected]49639fa2011-12-20 23:22:419504 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:299505
tfarina42834112016-09-22 13:38:209506 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019507 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]da81f132010-08-18 23:39:299508
9509 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019510 EXPECT_THAT(rv, IsOk());
[email protected]da81f132010-08-18 23:39:299511}
9512
bncd16676a2016-07-20 16:23:019513TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:429514 HttpRequestInfo request;
9515 request.method = "GET";
bncce36dca22015-04-21 22:11:239516 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:169517 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
9518 "http://the.previous.site.com/");
Ramin Halavatib5e433e2018-02-07 07:41:109519 request.traffic_annotation =
9520 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429521
danakj1fd259a02016-04-16 03:17:099522 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169523 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279524
[email protected]1c773ea12009-04-28 19:58:429525 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239526 MockWrite(
9527 "GET / HTTP/1.1\r\n"
9528 "Host: www.example.org\r\n"
9529 "Connection: keep-alive\r\n"
9530 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429531 };
9532
9533 // Lastly, the server responds with the actual content.
9534 MockRead data_reads[] = {
9535 MockRead("HTTP/1.0 200 OK\r\n"),
9536 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9537 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069538 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429539 };
9540
Ryan Sleevib8d7ea02018-05-07 20:01:019541 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079542 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429543
[email protected]49639fa2011-12-20 23:22:419544 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429545
tfarina42834112016-09-22 13:38:209546 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019547 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429548
9549 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019550 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429551}
9552
bncd16676a2016-07-20 16:23:019553TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429554 HttpRequestInfo request;
9555 request.method = "POST";
bncce36dca22015-04-21 22:11:239556 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109557 request.traffic_annotation =
9558 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429559
danakj1fd259a02016-04-16 03:17:099560 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169561 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279562
[email protected]1c773ea12009-04-28 19:58:429563 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239564 MockWrite(
9565 "POST / HTTP/1.1\r\n"
9566 "Host: www.example.org\r\n"
9567 "Connection: keep-alive\r\n"
9568 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429569 };
9570
9571 // Lastly, the server responds with the actual content.
9572 MockRead data_reads[] = {
9573 MockRead("HTTP/1.0 200 OK\r\n"),
9574 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9575 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069576 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429577 };
9578
Ryan Sleevib8d7ea02018-05-07 20:01:019579 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079580 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429581
[email protected]49639fa2011-12-20 23:22:419582 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429583
tfarina42834112016-09-22 13:38:209584 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019585 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429586
9587 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019588 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429589}
9590
bncd16676a2016-07-20 16:23:019591TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429592 HttpRequestInfo request;
9593 request.method = "PUT";
bncce36dca22015-04-21 22:11:239594 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109595 request.traffic_annotation =
9596 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429597
danakj1fd259a02016-04-16 03:17:099598 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169599 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279600
[email protected]1c773ea12009-04-28 19:58:429601 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239602 MockWrite(
9603 "PUT / HTTP/1.1\r\n"
9604 "Host: www.example.org\r\n"
9605 "Connection: keep-alive\r\n"
9606 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429607 };
9608
9609 // Lastly, the server responds with the actual content.
9610 MockRead data_reads[] = {
9611 MockRead("HTTP/1.0 200 OK\r\n"),
9612 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9613 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069614 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429615 };
9616
Ryan Sleevib8d7ea02018-05-07 20:01:019617 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079618 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429619
[email protected]49639fa2011-12-20 23:22:419620 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429621
tfarina42834112016-09-22 13:38:209622 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019623 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429624
9625 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019626 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429627}
9628
bncd16676a2016-07-20 16:23:019629TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:429630 HttpRequestInfo request;
9631 request.method = "HEAD";
bncce36dca22015-04-21 22:11:239632 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109633 request.traffic_annotation =
9634 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429635
danakj1fd259a02016-04-16 03:17:099636 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169637 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279638
[email protected]1c773ea12009-04-28 19:58:429639 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:139640 MockWrite("HEAD / HTTP/1.1\r\n"
9641 "Host: www.example.org\r\n"
9642 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429643 };
9644
9645 // Lastly, the server responds with the actual content.
9646 MockRead data_reads[] = {
9647 MockRead("HTTP/1.0 200 OK\r\n"),
9648 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9649 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069650 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429651 };
9652
Ryan Sleevib8d7ea02018-05-07 20:01:019653 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079654 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429655
[email protected]49639fa2011-12-20 23:22:419656 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429657
tfarina42834112016-09-22 13:38:209658 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019659 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429660
9661 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019662 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429663}
9664
bncd16676a2016-07-20 16:23:019665TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:429666 HttpRequestInfo request;
9667 request.method = "GET";
bncce36dca22015-04-21 22:11:239668 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429669 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:109670 request.traffic_annotation =
9671 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429672
danakj1fd259a02016-04-16 03:17:099673 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169674 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279675
[email protected]1c773ea12009-04-28 19:58:429676 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239677 MockWrite(
9678 "GET / HTTP/1.1\r\n"
9679 "Host: www.example.org\r\n"
9680 "Connection: keep-alive\r\n"
9681 "Pragma: no-cache\r\n"
9682 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429683 };
9684
9685 // Lastly, the server responds with the actual content.
9686 MockRead data_reads[] = {
9687 MockRead("HTTP/1.0 200 OK\r\n"),
9688 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9689 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069690 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429691 };
9692
Ryan Sleevib8d7ea02018-05-07 20:01:019693 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079694 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429695
[email protected]49639fa2011-12-20 23:22:419696 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429697
tfarina42834112016-09-22 13:38:209698 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019699 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429700
9701 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019702 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429703}
9704
bncd16676a2016-07-20 16:23:019705TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:429706 HttpRequestInfo request;
9707 request.method = "GET";
bncce36dca22015-04-21 22:11:239708 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:429709 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e2018-02-07 07:41:109710 request.traffic_annotation =
9711 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429712
danakj1fd259a02016-04-16 03:17:099713 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169714 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279715
[email protected]1c773ea12009-04-28 19:58:429716 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239717 MockWrite(
9718 "GET / HTTP/1.1\r\n"
9719 "Host: www.example.org\r\n"
9720 "Connection: keep-alive\r\n"
9721 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429722 };
9723
9724 // Lastly, the server responds with the actual content.
9725 MockRead data_reads[] = {
9726 MockRead("HTTP/1.0 200 OK\r\n"),
9727 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9728 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069729 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429730 };
9731
Ryan Sleevib8d7ea02018-05-07 20:01:019732 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079733 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429734
[email protected]49639fa2011-12-20 23:22:419735 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429736
tfarina42834112016-09-22 13:38:209737 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019738 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429739
9740 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019741 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429742}
9743
bncd16676a2016-07-20 16:23:019744TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:429745 HttpRequestInfo request;
9746 request.method = "GET";
bncce36dca22015-04-21 22:11:239747 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439748 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e2018-02-07 07:41:109749 request.traffic_annotation =
9750 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:429751
danakj1fd259a02016-04-16 03:17:099752 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169753 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279754
[email protected]1c773ea12009-04-28 19:58:429755 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239756 MockWrite(
9757 "GET / HTTP/1.1\r\n"
9758 "Host: www.example.org\r\n"
9759 "Connection: keep-alive\r\n"
9760 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:429761 };
9762
9763 // Lastly, the server responds with the actual content.
9764 MockRead data_reads[] = {
9765 MockRead("HTTP/1.0 200 OK\r\n"),
9766 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9767 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069768 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:429769 };
9770
Ryan Sleevib8d7ea02018-05-07 20:01:019771 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079772 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:429773
[email protected]49639fa2011-12-20 23:22:419774 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:429775
tfarina42834112016-09-22 13:38:209776 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019777 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:429778
9779 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019780 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:429781}
9782
bncd16676a2016-07-20 16:23:019783TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:479784 HttpRequestInfo request;
9785 request.method = "GET";
bncce36dca22015-04-21 22:11:239786 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:439787 request.extra_headers.SetHeader("referer", "www.foo.com");
9788 request.extra_headers.SetHeader("hEllo", "Kitty");
9789 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:109790 request.traffic_annotation =
9791 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:479792
danakj1fd259a02016-04-16 03:17:099793 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169794 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279795
[email protected]270c6412010-03-29 22:02:479796 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239797 MockWrite(
9798 "GET / HTTP/1.1\r\n"
9799 "Host: www.example.org\r\n"
9800 "Connection: keep-alive\r\n"
9801 "referer: www.foo.com\r\n"
9802 "hEllo: Kitty\r\n"
9803 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:479804 };
9805
9806 // Lastly, the server responds with the actual content.
9807 MockRead data_reads[] = {
9808 MockRead("HTTP/1.0 200 OK\r\n"),
9809 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9810 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069811 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:479812 };
9813
Ryan Sleevib8d7ea02018-05-07 20:01:019814 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079815 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:479816
[email protected]49639fa2011-12-20 23:22:419817 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:479818
tfarina42834112016-09-22 13:38:209819 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019820 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:479821
9822 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019823 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:479824}
9825
bncd16676a2016-07-20 16:23:019826TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279827 HttpRequestInfo request;
9828 request.method = "GET";
bncce36dca22015-04-21 22:11:239829 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109830 request.traffic_annotation =
9831 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279832
Lily Houghton8c2f97d2018-01-22 05:06:599833 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499834 ProxyResolutionService::CreateFixedFromPacResult(
9835 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519836 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079837 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029838
danakj1fd259a02016-04-16 03:17:099839 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169840 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029841
[email protected]3cd17242009-06-23 02:59:029842 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9843 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9844
9845 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239846 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9847 MockWrite(
9848 "GET / HTTP/1.1\r\n"
9849 "Host: www.example.org\r\n"
9850 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029851
9852 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:069853 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
[email protected]3cd17242009-06-23 02:59:029854 MockRead("HTTP/1.0 200 OK\r\n"),
9855 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9856 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069857 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:029858 };
9859
Ryan Sleevib8d7ea02018-05-07 20:01:019860 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079861 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:029862
[email protected]49639fa2011-12-20 23:22:419863 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:029864
tfarina42834112016-09-22 13:38:209865 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019866 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:029867
9868 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019869 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029870
bnc691fda62016-08-12 00:43:169871 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529872 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:029873
tbansal2ecbbc72016-10-06 17:15:479874 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:209875 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169876 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209877 TestLoadTimingNotReusedWithPac(load_timing_info,
9878 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
9879
[email protected]3cd17242009-06-23 02:59:029880 std::string response_text;
bnc691fda62016-08-12 00:43:169881 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019882 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:029883 EXPECT_EQ("Payload", response_text);
9884}
9885
bncd16676a2016-07-20 16:23:019886TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:279887 HttpRequestInfo request;
9888 request.method = "GET";
bncce36dca22015-04-21 22:11:239889 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109890 request.traffic_annotation =
9891 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:279892
Lily Houghton8c2f97d2018-01-22 05:06:599893 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499894 ProxyResolutionService::CreateFixedFromPacResult(
9895 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519896 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079897 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:029898
danakj1fd259a02016-04-16 03:17:099899 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169900 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:029901
[email protected]3cd17242009-06-23 02:59:029902 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
9903 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9904
9905 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239906 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
9907 arraysize(write_buffer)),
9908 MockWrite(
9909 "GET / HTTP/1.1\r\n"
9910 "Host: www.example.org\r\n"
9911 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:029912
9913 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:019914 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
9915 arraysize(read_buffer)),
[email protected]e0c27be2009-07-15 13:09:359916 MockRead("HTTP/1.0 200 OK\r\n"),
9917 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9918 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:069919 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:359920 };
9921
Ryan Sleevib8d7ea02018-05-07 20:01:019922 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079923 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:359924
[email protected]8ddf8322012-02-23 18:08:069925 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079926 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:359927
[email protected]49639fa2011-12-20 23:22:419928 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:359929
tfarina42834112016-09-22 13:38:209930 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019931 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:359932
9933 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019934 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359935
[email protected]029c83b62013-01-24 05:28:209936 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169937 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209938 TestLoadTimingNotReusedWithPac(load_timing_info,
9939 CONNECT_TIMING_HAS_SSL_TIMES);
9940
bnc691fda62016-08-12 00:43:169941 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529942 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:479943 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:359944
9945 std::string response_text;
bnc691fda62016-08-12 00:43:169946 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:019947 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:359948 EXPECT_EQ("Payload", response_text);
9949}
9950
bncd16676a2016-07-20 16:23:019951TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:209952 HttpRequestInfo request;
9953 request.method = "GET";
bncce36dca22015-04-21 22:11:239954 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:109955 request.traffic_annotation =
9956 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:209957
Ramin Halavatica8d5252018-03-12 05:33:499958 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9959 "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519960 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079961 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:209962
danakj1fd259a02016-04-16 03:17:099963 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169964 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:209965
9966 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
9967 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
9968
9969 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239970 MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
9971 MockWrite(
9972 "GET / HTTP/1.1\r\n"
9973 "Host: www.example.org\r\n"
9974 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:209975
9976 MockRead data_reads[] = {
9977 MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
9978 MockRead("HTTP/1.0 200 OK\r\n"),
9979 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
9980 MockRead("Payload"),
9981 MockRead(SYNCHRONOUS, OK)
9982 };
9983
Ryan Sleevib8d7ea02018-05-07 20:01:019984 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:079985 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:209986
9987 TestCompletionCallback callback;
9988
tfarina42834112016-09-22 13:38:209989 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019990 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:209991
9992 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019993 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:209994
bnc691fda62016-08-12 00:43:169995 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529996 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:209997
9998 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169999 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010000 TestLoadTimingNotReused(load_timing_info,
10001 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10002
10003 std::string response_text;
bnc691fda62016-08-12 00:43:1610004 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110005 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2010006 EXPECT_EQ("Payload", response_text);
10007}
10008
bncd16676a2016-07-20 16:23:0110009TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710010 HttpRequestInfo request;
10011 request.method = "GET";
bncce36dca22015-04-21 22:11:2310012 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010013 request.traffic_annotation =
10014 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710015
Lily Houghton8c2f97d2018-01-22 05:06:5910016 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910017 ProxyResolutionService::CreateFixedFromPacResult(
10018 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110019 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710020 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510021
danakj1fd259a02016-04-16 03:17:0910022 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610023 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510024
[email protected]e0c27be2009-07-15 13:09:3510025 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10026 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710027 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310028 0x05, // Version
10029 0x01, // Command (CONNECT)
10030 0x00, // Reserved.
10031 0x03, // Address type (DOMAINNAME).
10032 0x0F, // Length of domain (15)
10033 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10034 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:3710035 };
[email protected]e0c27be2009-07-15 13:09:3510036 const char kSOCKS5OkResponse[] =
10037 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
10038
10039 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310040 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
10041 MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
10042 MockWrite(
10043 "GET / HTTP/1.1\r\n"
10044 "Host: www.example.org\r\n"
10045 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510046
10047 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110048 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10049 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]e0c27be2009-07-15 13:09:3510050 MockRead("HTTP/1.0 200 OK\r\n"),
10051 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10052 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610053 MockRead(SYNCHRONOUS, OK)
[email protected]e0c27be2009-07-15 13:09:3510054 };
10055
Ryan Sleevib8d7ea02018-05-07 20:01:0110056 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710057 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510058
[email protected]49639fa2011-12-20 23:22:4110059 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510060
tfarina42834112016-09-22 13:38:2010061 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110062 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510063
10064 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110065 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510066
bnc691fda62016-08-12 00:43:1610067 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210068 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710069 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510070
[email protected]029c83b62013-01-24 05:28:2010071 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610072 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010073 TestLoadTimingNotReusedWithPac(load_timing_info,
10074 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10075
[email protected]e0c27be2009-07-15 13:09:3510076 std::string response_text;
bnc691fda62016-08-12 00:43:1610077 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110078 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510079 EXPECT_EQ("Payload", response_text);
10080}
10081
bncd16676a2016-07-20 16:23:0110082TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710083 HttpRequestInfo request;
10084 request.method = "GET";
bncce36dca22015-04-21 22:11:2310085 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010086 request.traffic_annotation =
10087 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710088
Lily Houghton8c2f97d2018-01-22 05:06:5910089 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910090 ProxyResolutionService::CreateFixedFromPacResult(
10091 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110092 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710093 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510094
danakj1fd259a02016-04-16 03:17:0910095 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610096 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510097
[email protected]e0c27be2009-07-15 13:09:3510098 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10099 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710100 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310101 0x05, // Version
10102 0x01, // Command (CONNECT)
10103 0x00, // Reserved.
10104 0x03, // Address type (DOMAINNAME).
10105 0x0F, // Length of domain (15)
10106 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10107 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3710108 };
10109
[email protected]e0c27be2009-07-15 13:09:3510110 const char kSOCKS5OkResponse[] =
10111 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
10112
10113 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310114 MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
10115 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
10116 arraysize(kSOCKS5OkRequest)),
10117 MockWrite(
10118 "GET / HTTP/1.1\r\n"
10119 "Host: www.example.org\r\n"
10120 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510121
10122 MockRead data_reads[] = {
[email protected]f871ee152012-07-27 19:02:0110123 MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
10124 MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
[email protected]3cd17242009-06-23 02:59:0210125 MockRead("HTTP/1.0 200 OK\r\n"),
10126 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10127 MockRead("Payload"),
[email protected]8ddf8322012-02-23 18:08:0610128 MockRead(SYNCHRONOUS, OK)
[email protected]3cd17242009-06-23 02:59:0210129 };
10130
Ryan Sleevib8d7ea02018-05-07 20:01:0110131 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710132 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210133
[email protected]8ddf8322012-02-23 18:08:0610134 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710135 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0210136
[email protected]49639fa2011-12-20 23:22:4110137 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210138
tfarina42834112016-09-22 13:38:2010139 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110140 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210141
10142 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110143 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210144
bnc691fda62016-08-12 00:43:1610145 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210146 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710147 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0210148
[email protected]029c83b62013-01-24 05:28:2010149 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610150 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010151 TestLoadTimingNotReusedWithPac(load_timing_info,
10152 CONNECT_TIMING_HAS_SSL_TIMES);
10153
[email protected]3cd17242009-06-23 02:59:0210154 std::string response_text;
bnc691fda62016-08-12 00:43:1610155 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110156 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210157 EXPECT_EQ("Payload", response_text);
10158}
10159
[email protected]448d4ca52012-03-04 04:12:2310160namespace {
10161
[email protected]04e5be32009-06-26 20:00:3110162// Tests that for connection endpoints the group names are correctly set.
[email protected]2d731a32010-04-29 01:04:0610163
10164struct GroupNameTest {
10165 std::string proxy_server;
10166 std::string url;
10167 std::string expected_group_name;
[email protected]e60e47a2010-07-14 03:37:1810168 bool ssl;
[email protected]2d731a32010-04-29 01:04:0610169};
10170
danakj1fd259a02016-04-16 03:17:0910171std::unique_ptr<HttpNetworkSession> SetupSessionForGroupNameTests(
[email protected]bb88e1d32013-05-03 23:11:0710172 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0910173 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0610174
bnc525e175a2016-06-20 12:36:4010175 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5310176 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2110177 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1210178 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2110179 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4210180 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4610181 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0610182
10183 return session;
10184}
10185
mmenkee65e7af2015-10-13 17:16:4210186int GroupNameTransactionHelper(const std::string& url,
10187 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0610188 HttpRequestInfo request;
10189 request.method = "GET";
10190 request.url = GURL(url);
Ramin Halavatib5e433e2018-02-07 07:41:1010191 request.traffic_annotation =
10192 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0610193
bnc691fda62016-08-12 00:43:1610194 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2710195
[email protected]49639fa2011-12-20 23:22:4110196 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0610197
10198 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2010199 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0610200}
10201
[email protected]448d4ca52012-03-04 04:12:2310202} // namespace
10203
bncd16676a2016-07-20 16:23:0110204TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
[email protected]2d731a32010-04-29 01:04:0610205 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310206 {
10207 "", // unused
10208 "http://www.example.org/direct",
10209 "www.example.org:80",
10210 false,
10211 },
10212 {
10213 "", // unused
10214 "http://[2001:1418:13:1::25]/direct",
10215 "[2001:1418:13:1::25]:80",
10216 false,
10217 },
[email protected]04e5be32009-06-26 20:00:3110218
bncce36dca22015-04-21 22:11:2310219 // SSL Tests
10220 {
10221 "", // unused
10222 "https://www.example.org/direct_ssl",
10223 "ssl/www.example.org:443",
10224 true,
10225 },
10226 {
10227 "", // unused
10228 "https://[2001:1418:13:1::25]/direct",
10229 "ssl/[2001:1418:13:1::25]:443",
10230 true,
10231 },
10232 {
10233 "", // unused
bncaa60ff402016-06-22 19:12:4210234 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310235 "ssl/host.with.alternate:443",
10236 true,
10237 },
[email protected]2d731a32010-04-29 01:04:0610238 };
[email protected]2ff8b312010-04-26 22:20:5410239
viettrungluue4a8b882014-10-16 06:17:3810240 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910241 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910242 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10243 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910244 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010245 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610246
mmenkee65e7af2015-10-13 17:16:4210247 HttpNetworkSessionPeer peer(session.get());
[email protected]ab739042011-04-07 15:22:2810248 CaptureGroupNameTransportSocketPool* transport_conn_pool =
bnc87dcefc2017-05-25 12:47:5810249 new CaptureGroupNameTransportSocketPool(nullptr, nullptr);
[email protected]2431756e2010-09-29 20:26:1310250 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
bnc87dcefc2017-05-25 12:47:5810251 new CaptureGroupNameSSLSocketPool(nullptr, nullptr);
Jeremy Roman0579ed62017-08-29 15:56:1910252 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0210253 mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
10254 mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
dchengc7eeda422015-12-26 03:56:4810255 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610256
10257 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210258 GroupNameTransactionHelper(tests[i].url, session.get()));
Tarun Bansal162eabe52018-01-20 01:16:3910259 if (tests[i].ssl) {
[email protected]e60e47a2010-07-14 03:37:1810260 EXPECT_EQ(tests[i].expected_group_name,
10261 ssl_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910262 } else {
[email protected]e60e47a2010-07-14 03:37:1810263 EXPECT_EQ(tests[i].expected_group_name,
[email protected]ab739042011-04-07 15:22:2810264 transport_conn_pool->last_group_name_received());
Tarun Bansal162eabe52018-01-20 01:16:3910265 }
10266 // When SSL proxy is in use, socket must be requested from |ssl_conn_pool|.
10267 EXPECT_EQ(tests[i].ssl, ssl_conn_pool->socket_requested());
10268 // When SSL proxy is not in use, socket must be requested from
10269 // |transport_conn_pool|.
10270 EXPECT_EQ(!tests[i].ssl, transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0610271 }
[email protected]2d731a32010-04-29 01:04:0610272}
10273
bncd16676a2016-07-20 16:23:0110274TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
[email protected]2d731a32010-04-29 01:04:0610275 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310276 {
Matt Menked1eb6d42018-01-17 04:54:0610277 "http_proxy", "http://www.example.org/http_proxy_normal",
10278 "http_proxy/www.example.org:80", false,
bncce36dca22015-04-21 22:11:2310279 },
[email protected]2d731a32010-04-29 01:04:0610280
bncce36dca22015-04-21 22:11:2310281 // SSL Tests
10282 {
Matt Menked1eb6d42018-01-17 04:54:0610283 "http_proxy", "https://www.example.org/http_connect_ssl",
10284 "http_proxy/ssl/www.example.org:443", true,
bncce36dca22015-04-21 22:11:2310285 },
[email protected]af3490e2010-10-16 21:02:2910286
bncce36dca22015-04-21 22:11:2310287 {
Matt Menked1eb6d42018-01-17 04:54:0610288 "http_proxy", "https://host.with.alternate/direct",
10289 "http_proxy/ssl/host.with.alternate:443", true,
bncce36dca22015-04-21 22:11:2310290 },
[email protected]45499252013-01-23 17:12:5610291
bncce36dca22015-04-21 22:11:2310292 {
Matt Menked1eb6d42018-01-17 04:54:0610293 "http_proxy", "ftp://ftp.google.com/http_proxy_normal",
10294 "http_proxy/ftp/ftp.google.com:21", false,
bncce36dca22015-04-21 22:11:2310295 },
[email protected]2d731a32010-04-29 01:04:0610296 };
10297
viettrungluue4a8b882014-10-16 06:17:3810298 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910299 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910300 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10301 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910302 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010303 SetupSessionForGroupNameTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0610304
mmenkee65e7af2015-10-13 17:16:4210305 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0610306
[email protected]e60e47a2010-07-14 03:37:1810307 HostPortPair proxy_host("http_proxy", 80);
[email protected]2431756e2010-09-29 20:26:1310308 CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
[email protected]9e1bdd32011-02-03 21:48:3410309 new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310310 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410311 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910312 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910313 mock_pool_manager->SetSocketPoolForHTTPProxy(
10314 proxy_host, base::WrapUnique(http_proxy_pool));
10315 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10316 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810317 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0610318
10319 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210320 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810321 if (tests[i].ssl)
10322 EXPECT_EQ(tests[i].expected_group_name,
10323 ssl_conn_pool->last_group_name_received());
10324 else
10325 EXPECT_EQ(tests[i].expected_group_name,
10326 http_proxy_pool->last_group_name_received());
[email protected]2d731a32010-04-29 01:04:0610327 }
[email protected]2d731a32010-04-29 01:04:0610328}
10329
bncd16676a2016-07-20 16:23:0110330TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
[email protected]2d731a32010-04-29 01:04:0610331 const GroupNameTest tests[] = {
bncce36dca22015-04-21 22:11:2310332 {
10333 "socks4://socks_proxy:1080",
10334 "http://www.example.org/socks4_direct",
10335 "socks4/www.example.org:80",
10336 false,
10337 },
10338 {
10339 "socks5://socks_proxy:1080",
10340 "http://www.example.org/socks5_direct",
10341 "socks5/www.example.org:80",
10342 false,
10343 },
[email protected]2d731a32010-04-29 01:04:0610344
bncce36dca22015-04-21 22:11:2310345 // SSL Tests
10346 {
10347 "socks4://socks_proxy:1080",
10348 "https://www.example.org/socks4_ssl",
10349 "socks4/ssl/www.example.org:443",
10350 true,
10351 },
10352 {
10353 "socks5://socks_proxy:1080",
10354 "https://www.example.org/socks5_ssl",
10355 "socks5/ssl/www.example.org:443",
10356 true,
10357 },
[email protected]af3490e2010-10-16 21:02:2910358
bncce36dca22015-04-21 22:11:2310359 {
10360 "socks4://socks_proxy:1080",
bncaa60ff402016-06-22 19:12:4210361 "https://host.with.alternate/direct",
bncce36dca22015-04-21 22:11:2310362 "socks4/ssl/host.with.alternate:443",
10363 true,
10364 },
[email protected]04e5be32009-06-26 20:00:3110365 };
10366
viettrungluue4a8b882014-10-16 06:17:3810367 for (size_t i = 0; i < arraysize(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5910368 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910369 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
10370 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0910371 std::unique_ptr<HttpNetworkSession> session(
bnca9b9e222016-07-11 20:10:4010372 SetupSessionForGroupNameTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0210373
mmenkee65e7af2015-10-13 17:16:4210374 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3110375
[email protected]e60e47a2010-07-14 03:37:1810376 HostPortPair proxy_host("socks_proxy", 1080);
[email protected]2431756e2010-09-29 20:26:1310377 CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410378 new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
[email protected]2431756e2010-09-29 20:26:1310379 CaptureGroupNameSSLSocketPool* ssl_conn_pool =
[email protected]9e1bdd32011-02-03 21:48:3410380 new CaptureGroupNameSSLSocketPool(NULL, NULL);
Jeremy Roman0579ed62017-08-29 15:56:1910381 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
aviadef3442016-10-03 18:50:3910382 mock_pool_manager->SetSocketPoolForSOCKSProxy(
10383 proxy_host, base::WrapUnique(socks_conn_pool));
10384 mock_pool_manager->SetSocketPoolForSSLWithProxy(
10385 proxy_host, base::WrapUnique(ssl_conn_pool));
dchengc7eeda422015-12-26 03:56:4810386 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3110387
bnc691fda62016-08-12 00:43:1610388 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3110389
[email protected]2d731a32010-04-29 01:04:0610390 EXPECT_EQ(ERR_IO_PENDING,
mmenkee65e7af2015-10-13 17:16:4210391 GroupNameTransactionHelper(tests[i].url, session.get()));
[email protected]e60e47a2010-07-14 03:37:1810392 if (tests[i].ssl)
10393 EXPECT_EQ(tests[i].expected_group_name,
10394 ssl_conn_pool->last_group_name_received());
10395 else
10396 EXPECT_EQ(tests[i].expected_group_name,
10397 socks_conn_pool->last_group_name_received());
[email protected]04e5be32009-06-26 20:00:3110398 }
10399}
10400
bncd16676a2016-07-20 16:23:0110401TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2710402 HttpRequestInfo request;
10403 request.method = "GET";
bncce36dca22015-04-21 22:11:2310404 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010405 request.traffic_annotation =
10406 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710407
Ramin Halavatica8d5252018-03-12 05:33:4910408 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10409 "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b59ff372009-07-15 22:04:3210410
[email protected]69719062010-01-05 20:09:2110411 // This simulates failure resolving all hostnames; that means we will fail
10412 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0710413 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3210414
danakj1fd259a02016-04-16 03:17:0910415 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610416 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2510417
[email protected]49639fa2011-12-20 23:22:4110418 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2510419
tfarina42834112016-09-22 13:38:2010420 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110421 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2510422
[email protected]9172a982009-06-06 00:30:2510423 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110424 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2510425}
10426
Miriam Gershenson2a01b162018-03-22 22:54:4710427// LOAD_BYPASS_CACHE should trigger the host cache bypass.
10428TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh) {
[email protected]cb9bf6ca2011-01-28 13:15:2710429 // Issue a request, asking to bypass the cache(s).
maksim.sisov31452af2016-07-27 06:38:1010430 HttpRequestInfo request_info;
10431 request_info.method = "GET";
Miriam Gershenson2a01b162018-03-22 22:54:4710432 request_info.load_flags = LOAD_BYPASS_CACHE;
maksim.sisov31452af2016-07-27 06:38:1010433 request_info.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010434 request_info.traffic_annotation =
10435 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710436
[email protected]a2c2fb92009-07-18 07:31:0410437 // Select a host resolver that does caching.
Jeremy Roman0579ed62017-08-29 15:56:1910438 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
[email protected]b59ff372009-07-15 22:04:3210439
danakj1fd259a02016-04-16 03:17:0910440 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610441 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3b9cca42009-06-16 01:08:2810442
bncce36dca22015-04-21 22:11:2310443 // Warm up the host cache so it has an entry for "www.example.org".
[email protected]3b9cca42009-06-16 01:08:2810444 AddressList addrlist;
[email protected]aa22b242011-11-16 18:58:2910445 TestCompletionCallback callback;
maksim.sisov31452af2016-07-27 06:38:1010446 std::unique_ptr<HostResolver::Request> request1;
[email protected]bb88e1d32013-05-03 23:11:0710447 int rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310448 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010449 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request1,
tfarina42834112016-09-22 13:38:2010450 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110451 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4710452 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110453 EXPECT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810454
10455 // Verify that it was added to host cache, by doing a subsequent async lookup
10456 // and confirming it completes synchronously.
maksim.sisov31452af2016-07-27 06:38:1010457 std::unique_ptr<HostResolver::Request> request2;
[email protected]bb88e1d32013-05-03 23:11:0710458 rv = session_deps_.host_resolver->Resolve(
bncce36dca22015-04-21 22:11:2310459 HostResolver::RequestInfo(HostPortPair("www.example.org", 80)),
maksim.sisov31452af2016-07-27 06:38:1010460 DEFAULT_PRIORITY, &addrlist, callback.callback(), &request2,
tfarina42834112016-09-22 13:38:2010461 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110462 ASSERT_THAT(rv, IsOk());
[email protected]3b9cca42009-06-16 01:08:2810463
bncce36dca22015-04-21 22:11:2310464 // Inject a failure the next time that "www.example.org" is resolved. This way
[email protected]3b9cca42009-06-16 01:08:2810465 // we can tell if the next lookup hit the cache, or the "network".
10466 // (cache --> success, "network" --> failure).
bncce36dca22015-04-21 22:11:2310467 session_deps_.host_resolver->rules()->AddSimulatedFailure("www.example.org");
[email protected]3b9cca42009-06-16 01:08:2810468
10469 // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
10470 // first read -- this won't be reached as the host resolution will fail first.
[email protected]8ddf8322012-02-23 18:08:0610471 MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
Ryan Sleevib8d7ea02018-05-07 20:01:0110472 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0710473 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3b9cca42009-06-16 01:08:2810474
[email protected]3b9cca42009-06-16 01:08:2810475 // Run the request.
tfarina42834112016-09-22 13:38:2010476 rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110477 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]49639fa2011-12-20 23:22:4110478 rv = callback.WaitForResult();
[email protected]3b9cca42009-06-16 01:08:2810479
10480 // If we bypassed the cache, we would have gotten a failure while resolving
bncce36dca22015-04-21 22:11:2310481 // "www.example.org".
robpercival214763f2016-07-01 23:27:0110482 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]3b9cca42009-06-16 01:08:2810483}
10484
[email protected]0877e3d2009-10-17 22:29:5710485// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0110486TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5710487 HttpRequestInfo request;
10488 request.method = "GET";
10489 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1010490 request.traffic_annotation =
10491 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710492
10493 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0610494 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710495 };
Ryan Sleevib8d7ea02018-05-07 20:01:0110496 StaticSocketDataProvider data(base::span<MockRead>(), write_failure);
[email protected]bb88e1d32013-05-03 23:11:0710497 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910498 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710499
[email protected]49639fa2011-12-20 23:22:4110500 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710501
bnc691fda62016-08-12 00:43:1610502 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710503
tfarina42834112016-09-22 13:38:2010504 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110505 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710506
10507 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110508 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5910509
10510 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610511 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910512 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710513}
10514
zmo9528c9f42015-08-04 22:12:0810515// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0110516TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5710517 HttpRequestInfo request;
10518 request.method = "GET";
10519 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1010520 request.traffic_annotation =
10521 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710522
10523 MockRead data_reads[] = {
10524 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0610525 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710526 };
10527
Ryan Sleevib8d7ea02018-05-07 20:01:0110528 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0710529 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0910530 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710531
[email protected]49639fa2011-12-20 23:22:4110532 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710533
bnc691fda62016-08-12 00:43:1610534 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710535
tfarina42834112016-09-22 13:38:2010536 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110537 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710538
10539 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110540 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810541
bnc691fda62016-08-12 00:43:1610542 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210543 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0810544
wezca1070932016-05-26 20:30:5210545 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0810546 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10547
10548 std::string response_data;
bnc691fda62016-08-12 00:43:1610549 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110550 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0810551 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5910552
10553 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1610554 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5910555 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5710556}
10557
10558// Make sure that a dropped connection while draining the body for auth
10559// restart does the right thing.
bncd16676a2016-07-20 16:23:0110560TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5710561 HttpRequestInfo request;
10562 request.method = "GET";
bncce36dca22015-04-21 22:11:2310563 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010564 request.traffic_annotation =
10565 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710566
10567 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310568 MockWrite(
10569 "GET / HTTP/1.1\r\n"
10570 "Host: www.example.org\r\n"
10571 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710572 };
10573
10574 MockRead data_reads1[] = {
10575 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
10576 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10577 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10578 MockRead("Content-Length: 14\r\n\r\n"),
10579 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0610580 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5710581 };
10582
Ryan Sleevib8d7ea02018-05-07 20:01:0110583 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0710584 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5710585
bnc691fda62016-08-12 00:43:1610586 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5710587 // be issuing -- the final header line contains the credentials.
10588 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310589 MockWrite(
10590 "GET / HTTP/1.1\r\n"
10591 "Host: www.example.org\r\n"
10592 "Connection: keep-alive\r\n"
10593 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5710594 };
10595
10596 // Lastly, the server responds with the actual content.
10597 MockRead data_reads2[] = {
10598 MockRead("HTTP/1.1 200 OK\r\n"),
10599 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10600 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610601 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5710602 };
10603
Ryan Sleevib8d7ea02018-05-07 20:01:0110604 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:0710605 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0910606 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5710607
[email protected]49639fa2011-12-20 23:22:4110608 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5710609
bnc691fda62016-08-12 00:43:1610610 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010611
tfarina42834112016-09-22 13:38:2010612 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110613 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710614
10615 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110616 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710617
bnc691fda62016-08-12 00:43:1610618 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210619 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410620 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
[email protected]0877e3d2009-10-17 22:29:5710621
[email protected]49639fa2011-12-20 23:22:4110622 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5710623
bnc691fda62016-08-12 00:43:1610624 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0110625 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710626
10627 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110628 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5710629
bnc691fda62016-08-12 00:43:1610630 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210631 ASSERT_TRUE(response);
10632 EXPECT_FALSE(response->auth_challenge);
[email protected]0877e3d2009-10-17 22:29:5710633 EXPECT_EQ(100, response->headers->GetContentLength());
10634}
10635
10636// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0110637TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Ramin Halavatica8d5252018-03-12 05:33:4910638 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10639 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710640
10641 HttpRequestInfo request;
10642 request.method = "GET";
bncce36dca22015-04-21 22:11:2310643 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010644 request.traffic_annotation =
10645 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5710646
10647 MockRead proxy_reads[] = {
10648 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0610649 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5710650 };
10651
Ryan Sleevib8d7ea02018-05-07 20:01:0110652 StaticSocketDataProvider data(proxy_reads, base::span<MockWrite>());
[email protected]8ddf8322012-02-23 18:08:0610653 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5710654
[email protected]bb88e1d32013-05-03 23:11:0710655 session_deps_.socket_factory->AddSocketDataProvider(&data);
10656 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5710657
[email protected]49639fa2011-12-20 23:22:4110658 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5710659
[email protected]bb88e1d32013-05-03 23:11:0710660 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5710661
danakj1fd259a02016-04-16 03:17:0910662 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610663 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5710664
tfarina42834112016-09-22 13:38:2010665 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110666 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5710667
10668 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110669 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5710670}
10671
bncd16676a2016-07-20 16:23:0110672TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4610673 HttpRequestInfo request;
10674 request.method = "GET";
bncce36dca22015-04-21 22:11:2310675 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010676 request.traffic_annotation =
10677 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4610678
danakj1fd259a02016-04-16 03:17:0910679 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610680 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710681
[email protected]e22e1362009-11-23 21:31:1210682 MockRead data_reads[] = {
10683 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610684 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1210685 };
[email protected]9492e4a2010-02-24 00:58:4610686
Ryan Sleevib8d7ea02018-05-07 20:01:0110687 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0710688 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4610689
[email protected]49639fa2011-12-20 23:22:4110690 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4610691
tfarina42834112016-09-22 13:38:2010692 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110693 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4610694
robpercival214763f2016-07-01 23:27:0110695 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4610696
bnc691fda62016-08-12 00:43:1610697 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210698 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4610699
wezca1070932016-05-26 20:30:5210700 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4610701 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
10702
10703 std::string response_data;
bnc691fda62016-08-12 00:43:1610704 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0110705 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1210706}
10707
bncd16676a2016-07-20 16:23:0110708TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1510709 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5210710 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1410711 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2110712 UploadFileElementReader::ScopedOverridingContentLengthForTests
10713 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3310714
danakj1fd259a02016-04-16 03:17:0910715 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910716 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410717 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0710718 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210719 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710720
10721 HttpRequestInfo request;
10722 request.method = "POST";
bncce36dca22015-04-21 22:11:2310723 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710724 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1010725 request.traffic_annotation =
10726 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710727
danakj1fd259a02016-04-16 03:17:0910728 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610729 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3310730
10731 MockRead data_reads[] = {
10732 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
10733 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0610734 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3310735 };
Ryan Sleevib8d7ea02018-05-07 20:01:0110736 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0710737 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3310738
[email protected]49639fa2011-12-20 23:22:4110739 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3310740
tfarina42834112016-09-22 13:38:2010741 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110742 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3310743
10744 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110745 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3310746
bnc691fda62016-08-12 00:43:1610747 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210748 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3310749
maksim.sisove869bf52016-06-23 17:11:5210750 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3310751
[email protected]dd3aa792013-07-16 19:10:2310752 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3310753}
10754
bncd16676a2016-07-20 16:23:0110755TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1510756 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5210757 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3610758 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4810759 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
10760 base::WriteFile(temp_file, temp_file_content.c_str(),
10761 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1110762 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3610763
danakj1fd259a02016-04-16 03:17:0910764 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1910765 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1410766 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0710767 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2210768 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2710769
10770 HttpRequestInfo request;
10771 request.method = "POST";
bncce36dca22015-04-21 22:11:2310772 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2710773 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1010774 request.traffic_annotation =
10775 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2710776
[email protected]999dd8c2013-11-12 06:45:5410777 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0910778 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610779 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3610780
Ryan Sleevib8d7ea02018-05-07 20:01:0110781 StaticSocketDataProvider data;
[email protected]bb88e1d32013-05-03 23:11:0710782 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3610783
[email protected]49639fa2011-12-20 23:22:4110784 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3610785
tfarina42834112016-09-22 13:38:2010786 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110787 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3610788
10789 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110790 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3610791
[email protected]dd3aa792013-07-16 19:10:2310792 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3610793}
10794
bncd16676a2016-07-20 16:23:0110795TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0310796 class FakeUploadElementReader : public UploadElementReader {
10797 public:
Chris Watkins7a41d3552017-12-01 02:13:2710798 FakeUploadElementReader() = default;
10799 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0310800
Matt Menkecc1d3a902018-02-05 18:27:3310801 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0310802
10803 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3310804 int Init(CompletionOnceCallback callback) override {
10805 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0310806 return ERR_IO_PENDING;
10807 }
avibf0746c2015-12-09 19:53:1410808 uint64_t GetContentLength() const override { return 0; }
10809 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2010810 int Read(IOBuffer* buf,
10811 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3310812 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0310813 return ERR_FAILED;
10814 }
10815
10816 private:
Matt Menkecc1d3a902018-02-05 18:27:3310817 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0310818 };
10819
10820 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0910821 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
10822 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2210823 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0310824
10825 HttpRequestInfo request;
10826 request.method = "POST";
bncce36dca22015-04-21 22:11:2310827 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0310828 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1010829 request.traffic_annotation =
10830 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0310831
danakj1fd259a02016-04-16 03:17:0910832 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5810833 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910834 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0310835
10836 StaticSocketDataProvider data;
10837 session_deps_.socket_factory->AddSocketDataProvider(&data);
10838
10839 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2010840 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110841 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5510842 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0310843
10844 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3310845 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
10846 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0310847
10848 // Return Init()'s result after the transaction gets destroyed.
10849 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3310850 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0310851}
10852
[email protected]aeefc9e82010-02-19 16:18:2710853// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0110854TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2710855 HttpRequestInfo request;
10856 request.method = "GET";
bncce36dca22015-04-21 22:11:2310857 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1010858 request.traffic_annotation =
10859 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2710860
10861 // First transaction will request a resource and receive a Basic challenge
10862 // with realm="first_realm".
10863 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2310864 MockWrite(
10865 "GET / HTTP/1.1\r\n"
10866 "Host: www.example.org\r\n"
10867 "Connection: keep-alive\r\n"
10868 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710869 };
10870 MockRead data_reads1[] = {
10871 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10872 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10873 "\r\n"),
10874 };
10875
bnc691fda62016-08-12 00:43:1610876 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2710877 // for first_realm. The server will reject and provide a challenge with
10878 // second_realm.
10879 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2310880 MockWrite(
10881 "GET / HTTP/1.1\r\n"
10882 "Host: www.example.org\r\n"
10883 "Connection: keep-alive\r\n"
10884 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
10885 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710886 };
10887 MockRead data_reads2[] = {
10888 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10889 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
10890 "\r\n"),
10891 };
10892
10893 // This again fails, and goes back to first_realm. Make sure that the
10894 // entry is removed from cache.
10895 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2310896 MockWrite(
10897 "GET / HTTP/1.1\r\n"
10898 "Host: www.example.org\r\n"
10899 "Connection: keep-alive\r\n"
10900 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
10901 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710902 };
10903 MockRead data_reads3[] = {
10904 MockRead("HTTP/1.1 401 Unauthorized\r\n"
10905 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
10906 "\r\n"),
10907 };
10908
10909 // Try one last time (with the correct password) and get the resource.
10910 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2310911 MockWrite(
10912 "GET / HTTP/1.1\r\n"
10913 "Host: www.example.org\r\n"
10914 "Connection: keep-alive\r\n"
10915 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
10916 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2710917 };
10918 MockRead data_reads4[] = {
10919 MockRead("HTTP/1.1 200 OK\r\n"
10920 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5010921 "Content-Length: 5\r\n"
10922 "\r\n"
10923 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2710924 };
10925
Ryan Sleevib8d7ea02018-05-07 20:01:0110926 StaticSocketDataProvider data1(data_reads1, data_writes1);
10927 StaticSocketDataProvider data2(data_reads2, data_writes2);
10928 StaticSocketDataProvider data3(data_reads3, data_writes3);
10929 StaticSocketDataProvider data4(data_reads4, data_writes4);
[email protected]bb88e1d32013-05-03 23:11:0710930 session_deps_.socket_factory->AddSocketDataProvider(&data1);
10931 session_deps_.socket_factory->AddSocketDataProvider(&data2);
10932 session_deps_.socket_factory->AddSocketDataProvider(&data3);
10933 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2710934
[email protected]49639fa2011-12-20 23:22:4110935 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2710936
danakj1fd259a02016-04-16 03:17:0910937 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610938 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5010939
[email protected]aeefc9e82010-02-19 16:18:2710940 // Issue the first request with Authorize headers. There should be a
10941 // password prompt for first_realm waiting to be filled in after the
10942 // transaction completes.
tfarina42834112016-09-22 13:38:2010943 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110944 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710945 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0110946 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610947 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210948 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410949 const AuthChallengeInfo* challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210950 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410951 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310952 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410953 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910954 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710955
10956 // Issue the second request with an incorrect password. There should be a
10957 // password prompt for second_realm waiting to be filled in after the
10958 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4110959 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1610960 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
10961 callback2.callback());
robpercival214763f2016-07-01 23:27:0110962 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710963 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0110964 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610965 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210966 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410967 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210968 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410969 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310970 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410971 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910972 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710973
10974 // Issue the third request with another incorrect password. There should be
10975 // a password prompt for first_realm waiting to be filled in. If the password
10976 // prompt is not present, it indicates that the HttpAuthCacheEntry for
10977 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4110978 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1610979 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
10980 callback3.callback());
robpercival214763f2016-07-01 23:27:0110981 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710982 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0110983 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1610984 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210985 ASSERT_TRUE(response);
[email protected]79cb5c12011-09-12 13:12:0410986 challenge = response->auth_challenge.get();
wezca1070932016-05-26 20:30:5210987 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0410988 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4310989 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0410990 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1910991 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2710992
10993 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4110994 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1610995 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
10996 callback4.callback());
robpercival214763f2016-07-01 23:27:0110997 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2710998 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0110999 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611000 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211001 ASSERT_TRUE(response);
11002 EXPECT_FALSE(response->auth_challenge);
[email protected]aeefc9e82010-02-19 16:18:2711003}
11004
Bence Béky230ac612017-08-30 19:17:0811005// Regression test for https://crbug.com/754395.
11006TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
11007 MockRead data_reads[] = {
11008 MockRead("HTTP/1.1 200 OK\r\n"),
11009 MockRead(kAlternativeServiceHttpHeader),
11010 MockRead("\r\n"),
11011 MockRead("hello world"),
11012 MockRead(SYNCHRONOUS, OK),
11013 };
11014
11015 HttpRequestInfo request;
11016 request.method = "GET";
11017 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011018 request.traffic_annotation =
11019 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0811020
Ryan Sleevib8d7ea02018-05-07 20:01:0111021 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:0811022 session_deps_.socket_factory->AddSocketDataProvider(&data);
11023
11024 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911025 ssl.ssl_info.cert =
11026 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11027 ASSERT_TRUE(ssl.ssl_info.cert);
11028 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0811029 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11030
11031 TestCompletionCallback callback;
11032
11033 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11034 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11035
11036 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11037 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11038
11039 url::SchemeHostPort test_server(request.url);
11040 HttpServerProperties* http_server_properties =
11041 session->http_server_properties();
11042 EXPECT_TRUE(
11043 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11044
11045 EXPECT_THAT(callback.WaitForResult(), IsOk());
11046
11047 const HttpResponseInfo* response = trans.GetResponseInfo();
11048 ASSERT_TRUE(response);
11049 ASSERT_TRUE(response->headers);
11050 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11051 EXPECT_FALSE(response->was_fetched_via_spdy);
11052 EXPECT_FALSE(response->was_alpn_negotiated);
11053
11054 std::string response_data;
11055 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11056 EXPECT_EQ("hello world", response_data);
11057
11058 EXPECT_TRUE(
11059 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11060}
11061
bncd16676a2016-07-20 16:23:0111062TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5211063 MockRead data_reads[] = {
11064 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311065 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211066 MockRead("\r\n"),
11067 MockRead("hello world"),
11068 MockRead(SYNCHRONOUS, OK),
11069 };
11070
11071 HttpRequestInfo request;
11072 request.method = "GET";
bncb26024382016-06-29 02:39:4511073 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011074 request.traffic_annotation =
11075 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211076
Ryan Sleevib8d7ea02018-05-07 20:01:0111077 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5211078 session_deps_.socket_factory->AddSocketDataProvider(&data);
11079
bncb26024382016-06-29 02:39:4511080 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911081 ssl.ssl_info.cert =
11082 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11083 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511084 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11085
bncc958faa2015-07-31 18:14:5211086 TestCompletionCallback callback;
11087
danakj1fd259a02016-04-16 03:17:0911088 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611089 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211090
tfarina42834112016-09-22 13:38:2011091 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111092 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211093
bncb26024382016-06-29 02:39:4511094 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011095 HttpServerProperties* http_server_properties =
11096 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411097 EXPECT_TRUE(
11098 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211099
robpercival214763f2016-07-01 23:27:0111100 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211101
bnc691fda62016-08-12 00:43:1611102 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211103 ASSERT_TRUE(response);
11104 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211105 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11106 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211107 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211108
11109 std::string response_data;
bnc691fda62016-08-12 00:43:1611110 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211111 EXPECT_EQ("hello world", response_data);
11112
zhongyic4de03032017-05-19 04:07:3411113 AlternativeServiceInfoVector alternative_service_info_vector =
11114 http_server_properties->GetAlternativeServiceInfos(test_server);
11115 ASSERT_EQ(1u, alternative_service_info_vector.size());
11116 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
11117 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411118 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5211119}
11120
bnce3dd56f2016-06-01 10:37:1111121// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0111122TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111123 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1111124 MockRead data_reads[] = {
11125 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311126 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1111127 MockRead("\r\n"),
11128 MockRead("hello world"),
11129 MockRead(SYNCHRONOUS, OK),
11130 };
11131
11132 HttpRequestInfo request;
11133 request.method = "GET";
11134 request.url = GURL("http://www.example.org/");
11135 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011136 request.traffic_annotation =
11137 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111138
Ryan Sleevib8d7ea02018-05-07 20:01:0111139 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1111140 session_deps_.socket_factory->AddSocketDataProvider(&data);
11141
11142 TestCompletionCallback callback;
11143
11144 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611145 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111146
11147 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011148 HttpServerProperties* http_server_properties =
11149 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411150 EXPECT_TRUE(
11151 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111152
tfarina42834112016-09-22 13:38:2011153 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111154 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11155 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1111156
bnc691fda62016-08-12 00:43:1611157 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1111158 ASSERT_TRUE(response);
11159 ASSERT_TRUE(response->headers);
11160 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11161 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211162 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1111163
11164 std::string response_data;
bnc691fda62016-08-12 00:43:1611165 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1111166 EXPECT_EQ("hello world", response_data);
11167
zhongyic4de03032017-05-19 04:07:3411168 EXPECT_TRUE(
11169 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1111170}
11171
bnca86731e2017-04-17 12:31:2811172// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2511173// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0111174TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2511175 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2811176 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4511177
bnc8bef8da22016-05-30 01:28:2511178 HttpRequestInfo request;
11179 request.method = "GET";
bncb26024382016-06-29 02:39:4511180 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2511181 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011182 request.traffic_annotation =
11183 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2511184
11185 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11186 StaticSocketDataProvider first_data;
11187 first_data.set_connect_data(mock_connect);
11188 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511189 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611190 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511191 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2511192
11193 MockRead data_reads[] = {
11194 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11195 MockRead(ASYNC, OK),
11196 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111197 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnc8bef8da22016-05-30 01:28:2511198 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11199
11200 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11201
bnc525e175a2016-06-20 12:36:4011202 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2511203 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111204 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
11205 444);
bnc8bef8da22016-05-30 01:28:2511206 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111207 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2511208 url::SchemeHostPort(request.url), alternative_service, expiration);
11209
bnc691fda62016-08-12 00:43:1611210 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2511211 TestCompletionCallback callback;
11212
tfarina42834112016-09-22 13:38:2011213 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2511214 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111215 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2511216}
11217
bnce3dd56f2016-06-01 10:37:1111218// Regression test for https://crbug.com/615497:
11219// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0111220TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1111221 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1111222 HttpRequestInfo request;
11223 request.method = "GET";
11224 request.url = GURL("http://www.example.org/");
11225 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011226 request.traffic_annotation =
11227 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1111228
11229 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11230 StaticSocketDataProvider first_data;
11231 first_data.set_connect_data(mock_connect);
11232 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
11233
11234 MockRead data_reads[] = {
11235 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
11236 MockRead(ASYNC, OK),
11237 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111238 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1111239 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
11240
11241 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11242
bnc525e175a2016-06-20 12:36:4011243 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1111244 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111245 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1111246 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111247 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1111248 url::SchemeHostPort(request.url), alternative_service, expiration);
11249
bnc691fda62016-08-12 00:43:1611250 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1111251 TestCompletionCallback callback;
11252
tfarina42834112016-09-22 13:38:2011253 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1111254 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0111255 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1111256}
11257
bncd16676a2016-07-20 16:23:0111258TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0811259 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0911260 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011261 HttpServerProperties* http_server_properties =
11262 session->http_server_properties();
bncb26024382016-06-29 02:39:4511263 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2111264 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0811265 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111266 http_server_properties->SetQuicAlternativeService(
11267 test_server, alternative_service, expiration,
11268 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3411269 EXPECT_EQ(
11270 1u,
11271 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0811272
11273 // Send a clear header.
11274 MockRead data_reads[] = {
11275 MockRead("HTTP/1.1 200 OK\r\n"),
11276 MockRead("Alt-Svc: clear\r\n"),
11277 MockRead("\r\n"),
11278 MockRead("hello world"),
11279 MockRead(SYNCHRONOUS, OK),
11280 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111281 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnc4f575852015-10-14 18:35:0811282 session_deps_.socket_factory->AddSocketDataProvider(&data);
11283
bncb26024382016-06-29 02:39:4511284 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911285 ssl.ssl_info.cert =
11286 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11287 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511288 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11289
bnc4f575852015-10-14 18:35:0811290 HttpRequestInfo request;
11291 request.method = "GET";
bncb26024382016-06-29 02:39:4511292 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011293 request.traffic_annotation =
11294 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0811295
11296 TestCompletionCallback callback;
11297
bnc691fda62016-08-12 00:43:1611298 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0811299
tfarina42834112016-09-22 13:38:2011300 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111301 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0811302
bnc691fda62016-08-12 00:43:1611303 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211304 ASSERT_TRUE(response);
11305 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0811306 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11307 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211308 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0811309
11310 std::string response_data;
bnc691fda62016-08-12 00:43:1611311 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0811312 EXPECT_EQ("hello world", response_data);
11313
zhongyic4de03032017-05-19 04:07:3411314 EXPECT_TRUE(
11315 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0811316}
11317
bncd16676a2016-07-20 16:23:0111318TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5211319 MockRead data_reads[] = {
11320 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311321 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
11322 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5211323 MockRead("hello world"),
11324 MockRead(SYNCHRONOUS, OK),
11325 };
11326
11327 HttpRequestInfo request;
11328 request.method = "GET";
bncb26024382016-06-29 02:39:4511329 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011330 request.traffic_annotation =
11331 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211332
Ryan Sleevib8d7ea02018-05-07 20:01:0111333 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5211334 session_deps_.socket_factory->AddSocketDataProvider(&data);
11335
bncb26024382016-06-29 02:39:4511336 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911337 ssl.ssl_info.cert =
11338 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11339 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511340 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11341
bncc958faa2015-07-31 18:14:5211342 TestCompletionCallback callback;
11343
danakj1fd259a02016-04-16 03:17:0911344 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611345 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211346
tfarina42834112016-09-22 13:38:2011347 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111348 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211349
bncb26024382016-06-29 02:39:4511350 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4011351 HttpServerProperties* http_server_properties =
11352 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411353 EXPECT_TRUE(
11354 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211355
robpercival214763f2016-07-01 23:27:0111356 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211357
bnc691fda62016-08-12 00:43:1611358 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211359 ASSERT_TRUE(response);
11360 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211361 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11362 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211363 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5211364
11365 std::string response_data;
bnc691fda62016-08-12 00:43:1611366 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5211367 EXPECT_EQ("hello world", response_data);
11368
zhongyic4de03032017-05-19 04:07:3411369 AlternativeServiceInfoVector alternative_service_info_vector =
11370 http_server_properties->GetAlternativeServiceInfos(test_server);
11371 ASSERT_EQ(2u, alternative_service_info_vector.size());
11372
11373 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
11374 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411375 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411376 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
11377 1234);
11378 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5411379 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5211380}
11381
bncd16676a2016-07-20 16:23:0111382TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611383 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211384 HostPortPair alternative("alternative.example.org", 443);
11385 std::string origin_url = "https://origin.example.org:443";
11386 std::string alternative_url = "https://alternative.example.org:443";
11387
11388 // Negotiate HTTP/1.1 with alternative.example.org.
11389 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611390 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211391 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11392
11393 // HTTP/1.1 data for request.
11394 MockWrite http_writes[] = {
11395 MockWrite("GET / HTTP/1.1\r\n"
11396 "Host: alternative.example.org\r\n"
11397 "Connection: keep-alive\r\n\r\n"),
11398 };
11399
11400 MockRead http_reads[] = {
11401 MockRead("HTTP/1.1 200 OK\r\n"
11402 "Content-Type: text/html; charset=iso-8859-1\r\n"
11403 "Content-Length: 40\r\n\r\n"
11404 "first HTTP/1.1 response from alternative"),
11405 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111406 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0211407 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11408
11409 StaticSocketDataProvider data_refused;
11410 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11411 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11412
zhongyi3d4a55e72016-04-22 20:36:4611413 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0911414 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011415 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211416 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111417 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0211418 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111419 http_server_properties->SetQuicAlternativeService(
11420 server, alternative_service, expiration,
11421 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0211422 // Mark the QUIC alternative service as broken.
11423 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
11424
zhongyi48704c182015-12-07 07:52:0211425 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611426 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211427 request.method = "GET";
11428 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1011429 request.traffic_annotation =
11430 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11431
zhongyi48704c182015-12-07 07:52:0211432 TestCompletionCallback callback;
11433 NetErrorDetails details;
11434 EXPECT_FALSE(details.quic_broken);
11435
tfarina42834112016-09-22 13:38:2011436 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611437 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211438 EXPECT_TRUE(details.quic_broken);
11439}
11440
bncd16676a2016-07-20 16:23:0111441TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4611442 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0211443 HostPortPair alternative1("alternative1.example.org", 443);
11444 HostPortPair alternative2("alternative2.example.org", 443);
11445 std::string origin_url = "https://origin.example.org:443";
11446 std::string alternative_url1 = "https://alternative1.example.org:443";
11447 std::string alternative_url2 = "https://alternative2.example.org:443";
11448
11449 // Negotiate HTTP/1.1 with alternative1.example.org.
11450 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611451 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0211452 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11453
11454 // HTTP/1.1 data for request.
11455 MockWrite http_writes[] = {
11456 MockWrite("GET / HTTP/1.1\r\n"
11457 "Host: alternative1.example.org\r\n"
11458 "Connection: keep-alive\r\n\r\n"),
11459 };
11460
11461 MockRead http_reads[] = {
11462 MockRead("HTTP/1.1 200 OK\r\n"
11463 "Content-Type: text/html; charset=iso-8859-1\r\n"
11464 "Content-Length: 40\r\n\r\n"
11465 "first HTTP/1.1 response from alternative1"),
11466 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111467 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0211468 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
11469
11470 StaticSocketDataProvider data_refused;
11471 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11472 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11473
danakj1fd259a02016-04-16 03:17:0911474 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4011475 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0211476 session->http_server_properties();
11477
zhongyi3d4a55e72016-04-22 20:36:4611478 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0211479 AlternativeServiceInfoVector alternative_service_info_vector;
11480 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
11481
bnc3472afd2016-11-17 15:27:2111482 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2111483 alternative_service_info_vector.push_back(
11484 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11485 alternative_service1, expiration,
11486 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2111487 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2111488 alternative_service_info_vector.push_back(
11489 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
11490 alternative_service2, expiration,
11491 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0211492
11493 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4611494 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0211495
11496 // Mark one of the QUIC alternative service as broken.
11497 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3411498 EXPECT_EQ(2u,
11499 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0211500
zhongyi48704c182015-12-07 07:52:0211501 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4611502 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0211503 request.method = "GET";
11504 request.url = GURL(origin_url);
Ramin Halavatib5e433e2018-02-07 07:41:1011505 request.traffic_annotation =
11506 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
11507
zhongyi48704c182015-12-07 07:52:0211508 TestCompletionCallback callback;
11509 NetErrorDetails details;
11510 EXPECT_FALSE(details.quic_broken);
11511
tfarina42834112016-09-22 13:38:2011512 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1611513 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0211514 EXPECT_FALSE(details.quic_broken);
11515}
11516
bncd16676a2016-07-20 16:23:0111517TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4211518 HttpRequestInfo request;
11519 request.method = "GET";
bncb26024382016-06-29 02:39:4511520 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011521 request.traffic_annotation =
11522 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4211523
[email protected]d973e99a2012-02-17 21:02:3611524 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4211525 StaticSocketDataProvider first_data;
11526 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711527 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4511528 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611529 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511530 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4211531
11532 MockRead data_reads[] = {
11533 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11534 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611535 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4211536 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111537 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711538 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4211539
danakj1fd259a02016-04-16 03:17:0911540 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4211541
bnc525e175a2016-06-20 12:36:4011542 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311543 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4611544 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1111545 // Port must be < 1024, or the header will be ignored (since initial port was
11546 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2111547 // Port is ignored by MockConnect anyway.
11548 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11549 666);
bnc7dc7e1b42015-07-28 14:43:1211550 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111551 http_server_properties->SetHttp2AlternativeService(
11552 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4211553
bnc691fda62016-08-12 00:43:1611554 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111555 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4211556
tfarina42834112016-09-22 13:38:2011557 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111558 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11559 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4211560
bnc691fda62016-08-12 00:43:1611561 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211562 ASSERT_TRUE(response);
11563 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4211564 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11565
11566 std::string response_data;
bnc691fda62016-08-12 00:43:1611567 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4211568 EXPECT_EQ("hello world", response_data);
11569
zhongyic4de03032017-05-19 04:07:3411570 const AlternativeServiceInfoVector alternative_service_info_vector =
11571 http_server_properties->GetAlternativeServiceInfos(server);
11572 ASSERT_EQ(1u, alternative_service_info_vector.size());
11573 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5411574 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3411575 EXPECT_TRUE(
11576 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4211577}
11578
bnc55ff9da2015-08-19 18:42:3511579// Ensure that we are not allowed to redirect traffic via an alternate protocol
11580// to an unrestricted (port >= 1024) when the original traffic was on a
11581// restricted port (port < 1024). Ensure that we can redirect in all other
11582// cases.
bncd16676a2016-07-20 16:23:0111583TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1111584 HttpRequestInfo restricted_port_request;
11585 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511586 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111587 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011588 restricted_port_request.traffic_annotation =
11589 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111590
[email protected]d973e99a2012-02-17 21:02:3611591 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111592 StaticSocketDataProvider first_data;
11593 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711594 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111595
11596 MockRead data_reads[] = {
11597 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11598 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611599 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111600 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111601 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711602 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511603 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611604 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511605 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111606
danakj1fd259a02016-04-16 03:17:0911607 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111608
bnc525e175a2016-06-20 12:36:4011609 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311610 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111611 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111612 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11613 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211614 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111615 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611616 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011617 expiration);
[email protected]3912662a32011-10-04 00:51:1111618
bnc691fda62016-08-12 00:43:1611619 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111620 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111621
tfarina42834112016-09-22 13:38:2011622 int rv = trans.Start(&restricted_port_request, callback.callback(),
11623 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111624 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111625 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0111626 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1911627}
[email protected]3912662a32011-10-04 00:51:1111628
bnc55ff9da2015-08-19 18:42:3511629// Ensure that we are allowed to redirect traffic via an alternate protocol to
11630// an unrestricted (port >= 1024) when the original traffic was on a restricted
11631// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0111632TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0711633 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1911634
11635 HttpRequestInfo restricted_port_request;
11636 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511637 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1911638 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011639 restricted_port_request.traffic_annotation =
11640 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1911641
11642 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
11643 StaticSocketDataProvider first_data;
11644 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711645 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1911646
11647 MockRead data_reads[] = {
11648 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11649 MockRead("hello world"),
11650 MockRead(ASYNC, OK),
11651 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111652 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711653 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511654 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611655 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511656 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1911657
danakj1fd259a02016-04-16 03:17:0911658 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1911659
bnc525e175a2016-06-20 12:36:4011660 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1911661 session->http_server_properties();
11662 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2111663 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11664 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211665 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111666 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611667 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011668 expiration);
[email protected]c54c6962013-02-01 04:53:1911669
bnc691fda62016-08-12 00:43:1611670 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1911671 TestCompletionCallback callback;
11672
tfarina42834112016-09-22 13:38:2011673 EXPECT_EQ(ERR_IO_PENDING,
11674 trans.Start(&restricted_port_request, callback.callback(),
11675 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1911676 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0111677 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111678}
11679
bnc55ff9da2015-08-19 18:42:3511680// Ensure that we are not allowed to redirect traffic via an alternate protocol
11681// to an unrestricted (port >= 1024) when the original traffic was on a
11682// restricted port (port < 1024). Ensure that we can redirect in all other
11683// cases.
bncd16676a2016-07-20 16:23:0111684TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1111685 HttpRequestInfo restricted_port_request;
11686 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511687 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1111688 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011689 restricted_port_request.traffic_annotation =
11690 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111691
[email protected]d973e99a2012-02-17 21:02:3611692 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111693 StaticSocketDataProvider first_data;
11694 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711695 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111696
11697 MockRead data_reads[] = {
11698 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11699 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611700 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111701 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111702 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711703 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111704
bncb26024382016-06-29 02:39:4511705 SSLSocketDataProvider ssl(ASYNC, OK);
11706 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11707
danakj1fd259a02016-04-16 03:17:0911708 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111709
bnc525e175a2016-06-20 12:36:4011710 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311711 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111712 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111713 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11714 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211715 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111716 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611717 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011718 expiration);
[email protected]3912662a32011-10-04 00:51:1111719
bnc691fda62016-08-12 00:43:1611720 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111721 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111722
tfarina42834112016-09-22 13:38:2011723 int rv = trans.Start(&restricted_port_request, callback.callback(),
11724 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111725 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111726 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111727 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111728}
11729
bnc55ff9da2015-08-19 18:42:3511730// Ensure that we are not allowed to redirect traffic via an alternate protocol
11731// to an unrestricted (port >= 1024) when the original traffic was on a
11732// restricted port (port < 1024). Ensure that we can redirect in all other
11733// cases.
bncd16676a2016-07-20 16:23:0111734TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1111735 HttpRequestInfo unrestricted_port_request;
11736 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511737 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111738 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011739 unrestricted_port_request.traffic_annotation =
11740 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111741
[email protected]d973e99a2012-02-17 21:02:3611742 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111743 StaticSocketDataProvider first_data;
11744 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711745 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111746
11747 MockRead data_reads[] = {
11748 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11749 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611750 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111751 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111752 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711753 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4511754 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611755 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511756 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1111757
danakj1fd259a02016-04-16 03:17:0911758 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111759
bnc525e175a2016-06-20 12:36:4011760 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311761 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1111762 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2111763 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11764 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211765 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111766 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611767 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011768 expiration);
[email protected]3912662a32011-10-04 00:51:1111769
bnc691fda62016-08-12 00:43:1611770 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111771 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111772
bnc691fda62016-08-12 00:43:1611773 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011774 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111775 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111776 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0111777 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111778}
11779
bnc55ff9da2015-08-19 18:42:3511780// Ensure that we are not allowed to redirect traffic via an alternate protocol
11781// to an unrestricted (port >= 1024) when the original traffic was on a
11782// restricted port (port < 1024). Ensure that we can redirect in all other
11783// cases.
bncd16676a2016-07-20 16:23:0111784TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1111785 HttpRequestInfo unrestricted_port_request;
11786 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4511787 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1111788 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1011789 unrestricted_port_request.traffic_annotation =
11790 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1111791
[email protected]d973e99a2012-02-17 21:02:3611792 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1111793 StaticSocketDataProvider first_data;
11794 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0711795 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1111796
11797 MockRead data_reads[] = {
11798 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11799 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611800 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1111801 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111802 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711803 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1111804
bncb26024382016-06-29 02:39:4511805 SSLSocketDataProvider ssl(ASYNC, OK);
11806 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11807
danakj1fd259a02016-04-16 03:17:0911808 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1111809
bnc525e175a2016-06-20 12:36:4011810 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311811 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2211812 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2111813 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11814 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1211815 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111816 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611817 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5011818 expiration);
[email protected]3912662a32011-10-04 00:51:1111819
bnc691fda62016-08-12 00:43:1611820 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4111821 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1111822
bnc691fda62016-08-12 00:43:1611823 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2011824 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111825 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1111826 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0111827 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1111828}
11829
bnc55ff9da2015-08-19 18:42:3511830// Ensure that we are not allowed to redirect traffic via an alternate protocol
Xida Chen9bfe0b62018-04-24 19:52:2111831// to an unsafe port, and that we resume the second HttpStreamFactory::Job once
11832// the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0111833TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0211834 HttpRequestInfo request;
11835 request.method = "GET";
bncce36dca22015-04-21 22:11:2311836 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011837 request.traffic_annotation =
11838 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0211839
11840 // The alternate protocol request will error out before we attempt to connect,
11841 // so only the standard HTTP request will try to connect.
11842 MockRead data_reads[] = {
11843 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
11844 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611845 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0211846 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111847 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711848 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0211849
danakj1fd259a02016-04-16 03:17:0911850 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0211851
bnc525e175a2016-06-20 12:36:4011852 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0211853 session->http_server_properties();
11854 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2111855 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
11856 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1211857 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111858 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4611859 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0211860
bnc691fda62016-08-12 00:43:1611861 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0211862 TestCompletionCallback callback;
11863
tfarina42834112016-09-22 13:38:2011864 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111865 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0211866 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0111867 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211868
bnc691fda62016-08-12 00:43:1611869 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211870 ASSERT_TRUE(response);
11871 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0211872 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11873
11874 std::string response_data;
bnc691fda62016-08-12 00:43:1611875 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0211876 EXPECT_EQ("hello world", response_data);
11877}
11878
bncd16676a2016-07-20 16:23:0111879TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5411880 HttpRequestInfo request;
11881 request.method = "GET";
bncb26024382016-06-29 02:39:4511882 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011883 request.traffic_annotation =
11884 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5411885
11886 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211887 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311888 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211889 MockRead("\r\n"),
11890 MockRead("hello world"),
11891 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11892 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5411893
Ryan Sleevib8d7ea02018-05-07 20:01:0111894 StaticSocketDataProvider first_transaction(data_reads,
11895 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711896 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4511897 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3611898 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4511899 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5411900
bnc032658ba2016-09-26 18:17:1511901 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5411902
Ryan Hamilton0239aac2018-05-19 00:03:1311903 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4511904 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4111905 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5411906
Ryan Hamilton0239aac2018-05-19 00:03:1311907 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
11908 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5411909 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4111910 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5411911 };
11912
Ryan Sleevib8d7ea02018-05-07 20:01:0111913 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0711914 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5411915
[email protected]d973e99a2012-02-17 21:02:3611916 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0111917 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5511918 hanging_non_alternate_protocol_socket.set_connect_data(
11919 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0711920 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5511921 &hanging_non_alternate_protocol_socket);
11922
[email protected]49639fa2011-12-20 23:22:4111923 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5411924
danakj1fd259a02016-04-16 03:17:0911925 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811926 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911927 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411928
tfarina42834112016-09-22 13:38:2011929 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111930 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11931 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411932
11933 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211934 ASSERT_TRUE(response);
11935 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5411936 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11937
11938 std::string response_data;
robpercival214763f2016-07-01 23:27:0111939 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411940 EXPECT_EQ("hello world", response_data);
11941
bnc87dcefc2017-05-25 12:47:5811942 trans =
Jeremy Roman0579ed62017-08-29 15:56:1911943 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5411944
tfarina42834112016-09-22 13:38:2011945 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111946 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11947 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411948
11949 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5211950 ASSERT_TRUE(response);
11951 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0211952 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5311953 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5211954 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5411955
robpercival214763f2016-07-01 23:27:0111956 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5411957 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5411958}
11959
bncd16676a2016-07-20 16:23:0111960TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5511961 HttpRequestInfo request;
11962 request.method = "GET";
bncb26024382016-06-29 02:39:4511963 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1011964 request.traffic_annotation =
11965 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5511966
bncb26024382016-06-29 02:39:4511967 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5511968 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5211969 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311970 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211971 MockRead("\r\n"),
11972 MockRead("hello world"),
11973 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
11974 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5511975 };
11976
Ryan Sleevib8d7ea02018-05-07 20:01:0111977 StaticSocketDataProvider http11_data(data_reads, base::span<MockWrite>());
bncb26024382016-06-29 02:39:4511978 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5511979
bncb26024382016-06-29 02:39:4511980 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911981 ssl_http11.ssl_info.cert =
11982 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11983 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4511984 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
11985
11986 // Second transaction starts an alternative and a non-alternative Job.
11987 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3611988 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0111989 StaticSocketDataProvider hanging_socket1;
mmenkecc2298e2015-12-07 18:20:1811990 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1811991 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
11992
Ryan Sleevib8d7ea02018-05-07 20:01:0111993 StaticSocketDataProvider hanging_socket2;
mmenkecc2298e2015-12-07 18:20:1811994 hanging_socket2.set_connect_data(never_finishing_connect);
11995 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5511996
bncb26024382016-06-29 02:39:4511997 // Third transaction starts an alternative and a non-alternative job.
11998 // The non-alternative job hangs, but the alternative one succeeds.
11999 // The second transaction, still pending, binds to this socket.
Ryan Hamilton0239aac2018-05-19 00:03:1312000 spdy::SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4512001 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1312002 spdy::SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4512003 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5512004 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4112005 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5512006 };
Ryan Hamilton0239aac2018-05-19 00:03:1312007 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
12008 spdy::SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
12009 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
12010 spdy::SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5512011 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112012 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
12013 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1312014 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5512015 };
12016
Ryan Sleevib8d7ea02018-05-07 20:01:0112017 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712018 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5512019
bnc032658ba2016-09-26 18:17:1512020 AddSSLSocketData();
bncb26024382016-06-29 02:39:4512021
Ryan Sleevib8d7ea02018-05-07 20:01:0112022 StaticSocketDataProvider hanging_socket3;
mmenkecc2298e2015-12-07 18:20:1812023 hanging_socket3.set_connect_data(never_finishing_connect);
12024 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5512025
danakj1fd259a02016-04-16 03:17:0912026 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4112027 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5012028 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512029
tfarina42834112016-09-22 13:38:2012030 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112031 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12032 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512033
12034 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212035 ASSERT_TRUE(response);
12036 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512037 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12038
12039 std::string response_data;
robpercival214763f2016-07-01 23:27:0112040 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512041 EXPECT_EQ("hello world", response_data);
12042
[email protected]49639fa2011-12-20 23:22:4112043 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5012044 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012045 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112046 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512047
[email protected]49639fa2011-12-20 23:22:4112048 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5012049 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012050 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112051 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512052
robpercival214763f2016-07-01 23:27:0112053 EXPECT_THAT(callback2.WaitForResult(), IsOk());
12054 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512055
12056 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212057 ASSERT_TRUE(response);
12058 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212059 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512060 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212061 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112062 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512063 EXPECT_EQ("hello!", response_data);
12064
12065 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5212066 ASSERT_TRUE(response);
12067 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212068 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512069 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212070 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112071 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512072 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5512073}
12074
bncd16676a2016-07-20 16:23:0112075TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
Bence Békybcae37092018-06-12 04:18:5312076 session_deps_.host_resolver->set_synchronous_mode(true);
12077
[email protected]2d6728692011-03-12 01:39:5512078 HttpRequestInfo request;
12079 request.method = "GET";
bncb26024382016-06-29 02:39:4512080 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012081 request.traffic_annotation =
12082 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512083
12084 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212085 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312086 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212087 MockRead("\r\n"),
12088 MockRead("hello world"),
12089 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12090 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512091 };
12092
Ryan Sleevib8d7ea02018-05-07 20:01:0112093 StaticSocketDataProvider first_transaction(data_reads,
12094 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712095 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5512096
[email protected]8ddf8322012-02-23 18:08:0612097 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912098 ssl.ssl_info.cert =
12099 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12100 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0712101 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512102
[email protected]d973e99a2012-02-17 21:02:3612103 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112104 StaticSocketDataProvider hanging_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512105 hanging_alternate_protocol_socket.set_connect_data(
12106 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712107 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512108 &hanging_alternate_protocol_socket);
12109
bncb26024382016-06-29 02:39:4512110 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
Ryan Sleevib8d7ea02018-05-07 20:01:0112111 StaticSocketDataProvider second_transaction(data_reads,
12112 base::span<MockWrite>());
mmenkecc2298e2015-12-07 18:20:1812113 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4512114 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512115
[email protected]49639fa2011-12-20 23:22:4112116 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5512117
danakj1fd259a02016-04-16 03:17:0912118 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812119 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912120 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512121
tfarina42834112016-09-22 13:38:2012122 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112123 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12124 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512125
12126 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212127 ASSERT_TRUE(response);
12128 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512129 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12130
12131 std::string response_data;
robpercival214763f2016-07-01 23:27:0112132 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512133 EXPECT_EQ("hello world", response_data);
12134
bnc87dcefc2017-05-25 12:47:5812135 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912136 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512137
tfarina42834112016-09-22 13:38:2012138 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112139 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12140 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512141
12142 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212143 ASSERT_TRUE(response);
12144 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512145 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12146 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212147 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5512148
robpercival214763f2016-07-01 23:27:0112149 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512150 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5512151}
12152
[email protected]631f1322010-04-30 17:59:1112153class CapturingProxyResolver : public ProxyResolver {
12154 public:
Chris Watkins7a41d3552017-12-01 02:13:2712155 CapturingProxyResolver() = default;
12156 ~CapturingProxyResolver() override = default;
[email protected]631f1322010-04-30 17:59:1112157
dchengb03027d2014-10-21 12:00:2012158 int GetProxyForURL(const GURL& url,
12159 ProxyInfo* results,
Bence Békycc5b88a2018-05-25 20:24:1712160 CompletionOnceCallback callback,
maksim.sisov7e157262016-10-20 11:19:5512161 std::unique_ptr<Request>* request,
tfarina42834112016-09-22 13:38:2012162 const NetLogWithSource& net_log) override {
[email protected]fae7669f2010-08-02 21:49:4012163 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
12164 HostPortPair("myproxy", 80));
[email protected]d911f1b2010-05-05 22:39:4212165 results->UseProxyServer(proxy_server);
[email protected]631f1322010-04-30 17:59:1112166 resolved_.push_back(url);
[email protected]d911f1b2010-05-05 22:39:4212167 return OK;
[email protected]631f1322010-04-30 17:59:1112168 }
12169
[email protected]24476402010-07-20 20:55:1712170 const std::vector<GURL>& resolved() const { return resolved_; }
12171
12172 private:
[email protected]631f1322010-04-30 17:59:1112173 std::vector<GURL> resolved_;
12174
12175 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
12176};
12177
sammce64b2362015-04-29 03:50:2312178class CapturingProxyResolverFactory : public ProxyResolverFactory {
12179 public:
12180 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
12181 : ProxyResolverFactory(false), resolver_(resolver) {}
12182
Lily Houghton99597862018-03-07 16:40:4212183 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
12184 std::unique_ptr<ProxyResolver>* resolver,
Bence Békycc5b88a2018-05-25 20:24:1712185 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:4212186 std::unique_ptr<Request>* request) override {
Jeremy Roman0579ed62017-08-29 15:56:1912187 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
sammce64b2362015-04-29 03:50:2312188 return OK;
12189 }
12190
12191 private:
12192 ProxyResolver* resolver_;
12193};
12194
bnc2e884782016-08-11 19:45:1912195// Test that proxy is resolved using the origin url,
12196// regardless of the alternative server.
12197TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
12198 // Configure proxy to bypass www.example.org, which is the origin URL.
12199 ProxyConfig proxy_config;
12200 proxy_config.proxy_rules().ParseFromString("myproxy:70");
12201 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
Ramin Halavatica8d5252018-03-12 05:33:4912202 auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
12203 ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
bnc2e884782016-08-11 19:45:1912204
12205 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1912206 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1912207 &capturing_proxy_resolver);
12208
12209 TestNetLog net_log;
12210
Bence Béky53a5aef2018-03-29 21:54:1212211 session_deps_.proxy_resolution_service =
12212 std::make_unique<ProxyResolutionService>(
12213 std::move(proxy_config_service), std::move(proxy_resolver_factory),
12214 &net_log);
bnc2e884782016-08-11 19:45:1912215
12216 session_deps_.net_log = &net_log;
12217
12218 // Configure alternative service with a hostname that is not bypassed by the
12219 // proxy.
12220 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12221 HttpServerProperties* http_server_properties =
12222 session->http_server_properties();
12223 url::SchemeHostPort server("https", "www.example.org", 443);
12224 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2112225 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1912226 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112227 http_server_properties->SetHttp2AlternativeService(
12228 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1912229
12230 // Non-alternative job should hang.
12231 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112232 StaticSocketDataProvider hanging_alternate_protocol_socket;
bnc2e884782016-08-11 19:45:1912233 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
12234 session_deps_.socket_factory->AddSocketDataProvider(
12235 &hanging_alternate_protocol_socket);
12236
bnc032658ba2016-09-26 18:17:1512237 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1912238
12239 HttpRequestInfo request;
12240 request.method = "GET";
12241 request.url = GURL("https://www.example.org/");
12242 request.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1012243 request.traffic_annotation =
12244 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1912245
Ryan Hamilton0239aac2018-05-19 00:03:1312246 spdy::SpdySerializedFrame req(
bnc2e884782016-08-11 19:45:1912247 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
12248
12249 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
12250
Ryan Hamilton0239aac2018-05-19 00:03:1312251 spdy::SpdySerializedFrame resp(
12252 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
12253 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc2e884782016-08-11 19:45:1912254 MockRead spdy_reads[] = {
12255 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
12256 };
12257
Ryan Sleevib8d7ea02018-05-07 20:01:0112258 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
bnc2e884782016-08-11 19:45:1912259 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
12260
12261 TestCompletionCallback callback;
12262
12263 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
12264
tfarina42834112016-09-22 13:38:2012265 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1912266 EXPECT_THAT(callback.GetResult(rv), IsOk());
12267
12268 const HttpResponseInfo* response = trans.GetResponseInfo();
12269 ASSERT_TRUE(response);
12270 ASSERT_TRUE(response->headers);
12271 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
12272 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212273 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1912274
12275 std::string response_data;
12276 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
12277 EXPECT_EQ("hello!", response_data);
12278
12279 // Origin host bypasses proxy, no resolution should have happened.
12280 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
12281}
12282
bncd16676a2016-07-20 16:23:0112283TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1112284 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4212285 proxy_config.set_auto_detect(true);
12286 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1112287
sammc5dd160c2015-04-02 02:43:1312288 CapturingProxyResolver capturing_proxy_resolver;
Ramin Halavatica8d5252018-03-12 05:33:4912289 session_deps_.proxy_resolution_service =
12290 std::make_unique<ProxyResolutionService>(
12291 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
12292 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
12293 std::make_unique<CapturingProxyResolverFactory>(
12294 &capturing_proxy_resolver),
12295 nullptr);
vishal.b62985ca92015-04-17 08:45:5112296 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0712297 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1112298
12299 HttpRequestInfo request;
12300 request.method = "GET";
bncb26024382016-06-29 02:39:4512301 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012302 request.traffic_annotation =
12303 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1112304
12305 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212306 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312307 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212308 MockRead("\r\n"),
12309 MockRead("hello world"),
12310 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12311 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1112312 };
12313
Ryan Sleevib8d7ea02018-05-07 20:01:0112314 StaticSocketDataProvider first_transaction(data_reads,
12315 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712316 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512317 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612318 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512319 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1112320
bnc032658ba2016-09-26 18:17:1512321 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1112322
Ryan Hamilton0239aac2018-05-19 00:03:1312323 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512324 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1112325 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1312326 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2512327 "CONNECT www.example.org:443 HTTP/1.1\r\n"
12328 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1312329 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4112330 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1112331 };
12332
[email protected]d911f1b2010-05-05 22:39:4212333 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
12334
Ryan Hamilton0239aac2018-05-19 00:03:1312335 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
12336 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1112337 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112338 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
12339 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1112340 };
12341
Ryan Sleevib8d7ea02018-05-07 20:01:0112342 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712343 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1112344
[email protected]d973e99a2012-02-17 21:02:3612345 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112346 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512347 hanging_non_alternate_protocol_socket.set_connect_data(
12348 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712349 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512350 &hanging_non_alternate_protocol_socket);
12351
[email protected]49639fa2011-12-20 23:22:4112352 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1112353
danakj1fd259a02016-04-16 03:17:0912354 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812355 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912356 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112357
tfarina42834112016-09-22 13:38:2012358 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4112359 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12360 EXPECT_THAT(callback.WaitForResult(), IsOk());
12361
12362 const HttpResponseInfo* response = trans->GetResponseInfo();
12363 ASSERT_TRUE(response);
12364 ASSERT_TRUE(response->headers);
12365 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
12366 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212367 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4112368
12369 std::string response_data;
12370 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
12371 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1112372
bnc87dcefc2017-05-25 12:47:5812373 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912374 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1112375
tfarina42834112016-09-22 13:38:2012376 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112377 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12378 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1112379
mmenkea2dcd3bf2016-08-16 21:49:4112380 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212381 ASSERT_TRUE(response);
12382 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212383 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312384 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212385 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1112386
robpercival214763f2016-07-01 23:27:0112387 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1112388 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4512389 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
12390 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312391 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2312392 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1312393 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1112394
[email protected]029c83b62013-01-24 05:28:2012395 LoadTimingInfo load_timing_info;
12396 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
12397 TestLoadTimingNotReusedWithPac(load_timing_info,
12398 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1112399}
[email protected]631f1322010-04-30 17:59:1112400
bncd16676a2016-07-20 16:23:0112401TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4812402 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5412403 HttpRequestInfo request;
12404 request.method = "GET";
bncb26024382016-06-29 02:39:4512405 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1012406 request.traffic_annotation =
12407 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412408
12409 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212410 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312411 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212412 MockRead("\r\n"),
12413 MockRead("hello world"),
12414 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5412415 };
12416
Ryan Sleevib8d7ea02018-05-07 20:01:0112417 StaticSocketDataProvider first_transaction(data_reads,
12418 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712419 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512420 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612421 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512422 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412423
bnc032658ba2016-09-26 18:17:1512424 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412425
Ryan Hamilton0239aac2018-05-19 00:03:1312426 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512427 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112428 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412429
Ryan Hamilton0239aac2018-05-19 00:03:1312430 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
12431 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412432 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112433 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412434 };
12435
Ryan Sleevib8d7ea02018-05-07 20:01:0112436 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712437 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412438
[email protected]83039bb2011-12-09 18:43:5512439 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412440
danakj1fd259a02016-04-16 03:17:0912441 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5412442
bnc87dcefc2017-05-25 12:47:5812443 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912444 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412445
tfarina42834112016-09-22 13:38:2012446 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112447 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12448 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412449
12450 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212451 ASSERT_TRUE(response);
12452 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412453 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12454
12455 std::string response_data;
robpercival214763f2016-07-01 23:27:0112456 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412457 EXPECT_EQ("hello world", response_data);
12458
12459 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2512460 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4012461 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0412462 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2712463 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5212464 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3812465
bnc87dcefc2017-05-25 12:47:5812466 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912467 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412468
tfarina42834112016-09-22 13:38:2012469 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112470 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12471 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412472
12473 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212474 ASSERT_TRUE(response);
12475 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212476 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312477 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212478 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412479
robpercival214763f2016-07-01 23:27:0112480 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412481 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4212482}
12483
[email protected]044de0642010-06-17 10:42:1512484// GenerateAuthToken is a mighty big test.
12485// It tests all permutation of GenerateAuthToken behavior:
12486// - Synchronous and Asynchronous completion.
12487// - OK or error on completion.
12488// - Direct connection, non-authenticating proxy, and authenticating proxy.
12489// - HTTP or HTTPS backend (to include proxy tunneling).
12490// - Non-authenticating and authenticating backend.
12491//
[email protected]fe3b7dc2012-02-03 19:52:0912492// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1512493// problems generating an auth token for an authenticating proxy, we don't
12494// need to test all permutations of the backend server).
12495//
12496// The test proceeds by going over each of the configuration cases, and
12497// potentially running up to three rounds in each of the tests. The TestConfig
12498// specifies both the configuration for the test as well as the expectations
12499// for the results.
bncd16676a2016-07-20 16:23:0112500TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5012501 static const char kServer[] = "http://www.example.com";
12502 static const char kSecureServer[] = "https://www.example.com";
12503 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1512504
12505 enum AuthTiming {
12506 AUTH_NONE,
12507 AUTH_SYNC,
12508 AUTH_ASYNC,
12509 };
12510
12511 const MockWrite kGet(
12512 "GET / HTTP/1.1\r\n"
12513 "Host: www.example.com\r\n"
12514 "Connection: keep-alive\r\n\r\n");
12515 const MockWrite kGetProxy(
12516 "GET http://www.example.com/ HTTP/1.1\r\n"
12517 "Host: www.example.com\r\n"
12518 "Proxy-Connection: keep-alive\r\n\r\n");
12519 const MockWrite kGetAuth(
12520 "GET / HTTP/1.1\r\n"
12521 "Host: www.example.com\r\n"
12522 "Connection: keep-alive\r\n"
12523 "Authorization: auth_token\r\n\r\n");
12524 const MockWrite kGetProxyAuth(
12525 "GET http://www.example.com/ HTTP/1.1\r\n"
12526 "Host: www.example.com\r\n"
12527 "Proxy-Connection: keep-alive\r\n"
12528 "Proxy-Authorization: auth_token\r\n\r\n");
12529 const MockWrite kGetAuthThroughProxy(
12530 "GET http://www.example.com/ HTTP/1.1\r\n"
12531 "Host: www.example.com\r\n"
12532 "Proxy-Connection: keep-alive\r\n"
12533 "Authorization: auth_token\r\n\r\n");
12534 const MockWrite kGetAuthWithProxyAuth(
12535 "GET http://www.example.com/ HTTP/1.1\r\n"
12536 "Host: www.example.com\r\n"
12537 "Proxy-Connection: keep-alive\r\n"
12538 "Proxy-Authorization: auth_token\r\n"
12539 "Authorization: auth_token\r\n\r\n");
12540 const MockWrite kConnect(
12541 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712542 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512543 "Proxy-Connection: keep-alive\r\n\r\n");
12544 const MockWrite kConnectProxyAuth(
12545 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1712546 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1512547 "Proxy-Connection: keep-alive\r\n"
12548 "Proxy-Authorization: auth_token\r\n\r\n");
12549
12550 const MockRead kSuccess(
12551 "HTTP/1.1 200 OK\r\n"
12552 "Content-Type: text/html; charset=iso-8859-1\r\n"
12553 "Content-Length: 3\r\n\r\n"
12554 "Yes");
12555 const MockRead kFailure(
12556 "Should not be called.");
12557 const MockRead kServerChallenge(
12558 "HTTP/1.1 401 Unauthorized\r\n"
12559 "WWW-Authenticate: Mock realm=server\r\n"
12560 "Content-Type: text/html; charset=iso-8859-1\r\n"
12561 "Content-Length: 14\r\n\r\n"
12562 "Unauthorized\r\n");
12563 const MockRead kProxyChallenge(
12564 "HTTP/1.1 407 Unauthorized\r\n"
12565 "Proxy-Authenticate: Mock realm=proxy\r\n"
12566 "Proxy-Connection: close\r\n"
12567 "Content-Type: text/html; charset=iso-8859-1\r\n"
12568 "Content-Length: 14\r\n\r\n"
12569 "Unauthorized\r\n");
12570 const MockRead kProxyConnected(
12571 "HTTP/1.1 200 Connection Established\r\n\r\n");
12572
12573 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
12574 // no constructors, but the C++ compiler on Windows warns about
12575 // unspecified data in compound literals. So, moved to using constructors,
12576 // and TestRound's created with the default constructor should not be used.
12577 struct TestRound {
12578 TestRound()
12579 : expected_rv(ERR_UNEXPECTED),
12580 extra_write(NULL),
12581 extra_read(NULL) {
12582 }
12583 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12584 int expected_rv_arg)
12585 : write(write_arg),
12586 read(read_arg),
12587 expected_rv(expected_rv_arg),
12588 extra_write(NULL),
12589 extra_read(NULL) {
12590 }
12591 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
12592 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0112593 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1512594 : write(write_arg),
12595 read(read_arg),
12596 expected_rv(expected_rv_arg),
12597 extra_write(extra_write_arg),
12598 extra_read(extra_read_arg) {
12599 }
12600 MockWrite write;
12601 MockRead read;
12602 int expected_rv;
12603 const MockWrite* extra_write;
12604 const MockRead* extra_read;
12605 };
12606
12607 static const int kNoSSL = 500;
12608
12609 struct TestConfig {
asanka463ca4262016-11-16 02:34:3112610 int line_number;
thestig9d3bb0c2015-01-24 00:49:5112611 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1512612 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3112613 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5112614 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1512615 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3112616 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1512617 int num_auth_rounds;
12618 int first_ssl_round;
asankae2257db2016-10-11 22:03:1612619 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1512620 } test_configs[] = {
asankac93076192016-10-03 15:46:0212621 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112622 {__LINE__,
12623 nullptr,
asankac93076192016-10-03 15:46:0212624 AUTH_NONE,
12625 OK,
12626 kServer,
12627 AUTH_NONE,
12628 OK,
12629 1,
12630 kNoSSL,
12631 {TestRound(kGet, kSuccess, OK)}},
12632 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3112633 {__LINE__,
12634 nullptr,
asankac93076192016-10-03 15:46:0212635 AUTH_NONE,
12636 OK,
12637 kServer,
12638 AUTH_SYNC,
12639 OK,
12640 2,
12641 kNoSSL,
12642 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512643 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112644 {__LINE__,
12645 nullptr,
asankac93076192016-10-03 15:46:0212646 AUTH_NONE,
12647 OK,
12648 kServer,
12649 AUTH_SYNC,
12650 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612651 3,
12652 kNoSSL,
12653 {TestRound(kGet, kServerChallenge, OK),
12654 TestRound(kGet, kServerChallenge, OK),
12655 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112656 {__LINE__,
12657 nullptr,
asankae2257db2016-10-11 22:03:1612658 AUTH_NONE,
12659 OK,
12660 kServer,
12661 AUTH_SYNC,
12662 ERR_UNSUPPORTED_AUTH_SCHEME,
12663 2,
12664 kNoSSL,
12665 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112666 {__LINE__,
12667 nullptr,
asankae2257db2016-10-11 22:03:1612668 AUTH_NONE,
12669 OK,
12670 kServer,
12671 AUTH_SYNC,
12672 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
12673 2,
12674 kNoSSL,
12675 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112676 {__LINE__,
12677 kProxy,
asankae2257db2016-10-11 22:03:1612678 AUTH_SYNC,
12679 ERR_FAILED,
12680 kServer,
12681 AUTH_NONE,
12682 OK,
12683 2,
12684 kNoSSL,
12685 {TestRound(kGetProxy, kProxyChallenge, OK),
12686 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112687 {__LINE__,
12688 kProxy,
asankae2257db2016-10-11 22:03:1612689 AUTH_ASYNC,
12690 ERR_FAILED,
12691 kServer,
12692 AUTH_NONE,
12693 OK,
12694 2,
12695 kNoSSL,
12696 {TestRound(kGetProxy, kProxyChallenge, OK),
12697 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112698 {__LINE__,
12699 nullptr,
asankae2257db2016-10-11 22:03:1612700 AUTH_NONE,
12701 OK,
12702 kServer,
12703 AUTH_SYNC,
12704 ERR_FAILED,
asankac93076192016-10-03 15:46:0212705 2,
12706 kNoSSL,
12707 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612708 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112709 {__LINE__,
12710 nullptr,
asankae2257db2016-10-11 22:03:1612711 AUTH_NONE,
12712 OK,
12713 kServer,
12714 AUTH_ASYNC,
12715 ERR_FAILED,
12716 2,
12717 kNoSSL,
12718 {TestRound(kGet, kServerChallenge, OK),
12719 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3112720 {__LINE__,
12721 nullptr,
asankac93076192016-10-03 15:46:0212722 AUTH_NONE,
12723 OK,
12724 kServer,
12725 AUTH_ASYNC,
12726 OK,
12727 2,
12728 kNoSSL,
12729 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512730 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112731 {__LINE__,
12732 nullptr,
asankac93076192016-10-03 15:46:0212733 AUTH_NONE,
12734 OK,
12735 kServer,
12736 AUTH_ASYNC,
12737 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612738 3,
asankac93076192016-10-03 15:46:0212739 kNoSSL,
12740 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612741 // The second round uses a HttpAuthHandlerMock that always succeeds.
12742 TestRound(kGet, kServerChallenge, OK),
12743 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212744 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112745 {__LINE__,
12746 kProxy,
asankac93076192016-10-03 15:46:0212747 AUTH_NONE,
12748 OK,
12749 kServer,
12750 AUTH_NONE,
12751 OK,
12752 1,
12753 kNoSSL,
12754 {TestRound(kGetProxy, kSuccess, OK)}},
12755 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3112756 {__LINE__,
12757 kProxy,
asankac93076192016-10-03 15:46:0212758 AUTH_NONE,
12759 OK,
12760 kServer,
12761 AUTH_SYNC,
12762 OK,
12763 2,
12764 kNoSSL,
12765 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512766 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112767 {__LINE__,
12768 kProxy,
asankac93076192016-10-03 15:46:0212769 AUTH_NONE,
12770 OK,
12771 kServer,
12772 AUTH_SYNC,
12773 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1612774 3,
asankac93076192016-10-03 15:46:0212775 kNoSSL,
12776 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612777 TestRound(kGetProxy, kServerChallenge, OK),
12778 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112779 {__LINE__,
12780 kProxy,
asankac93076192016-10-03 15:46:0212781 AUTH_NONE,
12782 OK,
12783 kServer,
12784 AUTH_ASYNC,
12785 OK,
12786 2,
12787 kNoSSL,
12788 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512789 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112790 {__LINE__,
12791 kProxy,
asankac93076192016-10-03 15:46:0212792 AUTH_NONE,
12793 OK,
12794 kServer,
12795 AUTH_ASYNC,
12796 ERR_INVALID_AUTH_CREDENTIALS,
12797 2,
12798 kNoSSL,
12799 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612800 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212801 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112802 {__LINE__,
12803 kProxy,
asankac93076192016-10-03 15:46:0212804 AUTH_SYNC,
12805 OK,
12806 kServer,
12807 AUTH_NONE,
12808 OK,
12809 2,
12810 kNoSSL,
12811 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512812 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112813 {__LINE__,
12814 kProxy,
asankac93076192016-10-03 15:46:0212815 AUTH_SYNC,
12816 ERR_INVALID_AUTH_CREDENTIALS,
12817 kServer,
12818 AUTH_NONE,
12819 OK,
12820 2,
12821 kNoSSL,
12822 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612823 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112824 {__LINE__,
12825 kProxy,
asankac93076192016-10-03 15:46:0212826 AUTH_ASYNC,
12827 OK,
12828 kServer,
12829 AUTH_NONE,
12830 OK,
12831 2,
12832 kNoSSL,
12833 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512834 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112835 {__LINE__,
12836 kProxy,
asankac93076192016-10-03 15:46:0212837 AUTH_ASYNC,
12838 ERR_INVALID_AUTH_CREDENTIALS,
12839 kServer,
12840 AUTH_NONE,
12841 OK,
12842 2,
12843 kNoSSL,
12844 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1612845 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112846 {__LINE__,
12847 kProxy,
12848 AUTH_ASYNC,
12849 ERR_INVALID_AUTH_CREDENTIALS,
12850 kServer,
12851 AUTH_NONE,
12852 OK,
12853 3,
12854 kNoSSL,
12855 {TestRound(kGetProxy, kProxyChallenge, OK),
12856 TestRound(kGetProxy, kProxyChallenge, OK),
12857 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212858 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3112859 {__LINE__,
12860 kProxy,
asankac93076192016-10-03 15:46:0212861 AUTH_SYNC,
12862 OK,
12863 kServer,
12864 AUTH_SYNC,
12865 OK,
12866 3,
12867 kNoSSL,
12868 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512869 TestRound(kGetProxyAuth, kServerChallenge, OK),
12870 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112871 {__LINE__,
12872 kProxy,
asankac93076192016-10-03 15:46:0212873 AUTH_SYNC,
12874 OK,
12875 kServer,
12876 AUTH_SYNC,
12877 ERR_INVALID_AUTH_CREDENTIALS,
12878 3,
12879 kNoSSL,
12880 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512881 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612882 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112883 {__LINE__,
12884 kProxy,
asankac93076192016-10-03 15:46:0212885 AUTH_ASYNC,
12886 OK,
12887 kServer,
12888 AUTH_SYNC,
12889 OK,
12890 3,
12891 kNoSSL,
12892 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512893 TestRound(kGetProxyAuth, kServerChallenge, OK),
12894 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112895 {__LINE__,
12896 kProxy,
asankac93076192016-10-03 15:46:0212897 AUTH_ASYNC,
12898 OK,
12899 kServer,
12900 AUTH_SYNC,
12901 ERR_INVALID_AUTH_CREDENTIALS,
12902 3,
12903 kNoSSL,
12904 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512905 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612906 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112907 {__LINE__,
12908 kProxy,
asankac93076192016-10-03 15:46:0212909 AUTH_SYNC,
12910 OK,
12911 kServer,
12912 AUTH_ASYNC,
12913 OK,
12914 3,
12915 kNoSSL,
12916 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512917 TestRound(kGetProxyAuth, kServerChallenge, OK),
12918 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112919 {__LINE__,
12920 kProxy,
12921 AUTH_SYNC,
12922 ERR_INVALID_AUTH_CREDENTIALS,
12923 kServer,
12924 AUTH_ASYNC,
12925 OK,
12926 4,
12927 kNoSSL,
12928 {TestRound(kGetProxy, kProxyChallenge, OK),
12929 TestRound(kGetProxy, kProxyChallenge, OK),
12930 TestRound(kGetProxyAuth, kServerChallenge, OK),
12931 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
12932 {__LINE__,
12933 kProxy,
asankac93076192016-10-03 15:46:0212934 AUTH_SYNC,
12935 OK,
12936 kServer,
12937 AUTH_ASYNC,
12938 ERR_INVALID_AUTH_CREDENTIALS,
12939 3,
12940 kNoSSL,
12941 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512942 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612943 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112944 {__LINE__,
12945 kProxy,
asankac93076192016-10-03 15:46:0212946 AUTH_ASYNC,
12947 OK,
12948 kServer,
12949 AUTH_ASYNC,
12950 OK,
12951 3,
12952 kNoSSL,
12953 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512954 TestRound(kGetProxyAuth, kServerChallenge, OK),
12955 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112956 {__LINE__,
12957 kProxy,
asankac93076192016-10-03 15:46:0212958 AUTH_ASYNC,
12959 OK,
12960 kServer,
12961 AUTH_ASYNC,
12962 ERR_INVALID_AUTH_CREDENTIALS,
12963 3,
12964 kNoSSL,
12965 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1512966 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1612967 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3112968 {__LINE__,
12969 kProxy,
12970 AUTH_ASYNC,
12971 ERR_INVALID_AUTH_CREDENTIALS,
12972 kServer,
12973 AUTH_ASYNC,
12974 ERR_INVALID_AUTH_CREDENTIALS,
12975 4,
12976 kNoSSL,
12977 {TestRound(kGetProxy, kProxyChallenge, OK),
12978 TestRound(kGetProxy, kProxyChallenge, OK),
12979 TestRound(kGetProxyAuth, kServerChallenge, OK),
12980 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0212981 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112982 {__LINE__,
12983 nullptr,
asankac93076192016-10-03 15:46:0212984 AUTH_NONE,
12985 OK,
12986 kSecureServer,
12987 AUTH_NONE,
12988 OK,
12989 1,
12990 0,
12991 {TestRound(kGet, kSuccess, OK)}},
12992 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3112993 {__LINE__,
12994 nullptr,
asankac93076192016-10-03 15:46:0212995 AUTH_NONE,
12996 OK,
12997 kSecureServer,
12998 AUTH_SYNC,
12999 OK,
13000 2,
13001 0,
13002 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513003 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113004 {__LINE__,
13005 nullptr,
asankac93076192016-10-03 15:46:0213006 AUTH_NONE,
13007 OK,
13008 kSecureServer,
13009 AUTH_SYNC,
13010 ERR_INVALID_AUTH_CREDENTIALS,
13011 2,
13012 0,
asankae2257db2016-10-11 22:03:1613013 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113014 {__LINE__,
13015 nullptr,
asankac93076192016-10-03 15:46:0213016 AUTH_NONE,
13017 OK,
13018 kSecureServer,
13019 AUTH_ASYNC,
13020 OK,
13021 2,
13022 0,
13023 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513024 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113025 {__LINE__,
13026 nullptr,
asankac93076192016-10-03 15:46:0213027 AUTH_NONE,
13028 OK,
13029 kSecureServer,
13030 AUTH_ASYNC,
13031 ERR_INVALID_AUTH_CREDENTIALS,
13032 2,
13033 0,
asankae2257db2016-10-11 22:03:1613034 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213035 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113036 {__LINE__,
13037 kProxy,
asankac93076192016-10-03 15:46:0213038 AUTH_NONE,
13039 OK,
13040 kSecureServer,
13041 AUTH_NONE,
13042 OK,
13043 1,
13044 0,
13045 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
13046 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113047 {__LINE__,
13048 kProxy,
asankac93076192016-10-03 15:46:0213049 AUTH_NONE,
13050 OK,
13051 kSecureServer,
13052 AUTH_SYNC,
13053 OK,
13054 2,
13055 0,
13056 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513057 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113058 {__LINE__,
13059 kProxy,
asankac93076192016-10-03 15:46:0213060 AUTH_NONE,
13061 OK,
13062 kSecureServer,
13063 AUTH_SYNC,
13064 ERR_INVALID_AUTH_CREDENTIALS,
13065 2,
13066 0,
13067 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613068 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113069 {__LINE__,
13070 kProxy,
asankac93076192016-10-03 15:46:0213071 AUTH_NONE,
13072 OK,
13073 kSecureServer,
13074 AUTH_ASYNC,
13075 OK,
13076 2,
13077 0,
13078 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513079 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113080 {__LINE__,
13081 kProxy,
asankac93076192016-10-03 15:46:0213082 AUTH_NONE,
13083 OK,
13084 kSecureServer,
13085 AUTH_ASYNC,
13086 ERR_INVALID_AUTH_CREDENTIALS,
13087 2,
13088 0,
13089 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613090 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213091 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113092 {__LINE__,
13093 kProxy,
asankac93076192016-10-03 15:46:0213094 AUTH_SYNC,
13095 OK,
13096 kSecureServer,
13097 AUTH_NONE,
13098 OK,
13099 2,
13100 1,
13101 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513102 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113103 {__LINE__,
13104 kProxy,
asankac93076192016-10-03 15:46:0213105 AUTH_SYNC,
13106 ERR_INVALID_AUTH_CREDENTIALS,
13107 kSecureServer,
13108 AUTH_NONE,
13109 OK,
13110 2,
13111 kNoSSL,
13112 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613113 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113114 {__LINE__,
13115 kProxy,
asankae2257db2016-10-11 22:03:1613116 AUTH_SYNC,
13117 ERR_UNSUPPORTED_AUTH_SCHEME,
13118 kSecureServer,
13119 AUTH_NONE,
13120 OK,
13121 2,
13122 kNoSSL,
13123 {TestRound(kConnect, kProxyChallenge, OK),
13124 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113125 {__LINE__,
13126 kProxy,
asankae2257db2016-10-11 22:03:1613127 AUTH_SYNC,
13128 ERR_UNEXPECTED,
13129 kSecureServer,
13130 AUTH_NONE,
13131 OK,
13132 2,
13133 kNoSSL,
13134 {TestRound(kConnect, kProxyChallenge, OK),
13135 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3113136 {__LINE__,
13137 kProxy,
asankac93076192016-10-03 15:46:0213138 AUTH_ASYNC,
13139 OK,
13140 kSecureServer,
13141 AUTH_NONE,
13142 OK,
13143 2,
13144 1,
13145 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513146 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113147 {__LINE__,
13148 kProxy,
asankac93076192016-10-03 15:46:0213149 AUTH_ASYNC,
13150 ERR_INVALID_AUTH_CREDENTIALS,
13151 kSecureServer,
13152 AUTH_NONE,
13153 OK,
13154 2,
13155 kNoSSL,
13156 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613157 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0213158 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113159 {__LINE__,
13160 kProxy,
asankac93076192016-10-03 15:46:0213161 AUTH_SYNC,
13162 OK,
13163 kSecureServer,
13164 AUTH_SYNC,
13165 OK,
13166 3,
13167 1,
13168 {TestRound(kConnect, kProxyChallenge, OK),
13169 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13170 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513171 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113172 {__LINE__,
13173 kProxy,
asankac93076192016-10-03 15:46:0213174 AUTH_SYNC,
13175 OK,
13176 kSecureServer,
13177 AUTH_SYNC,
13178 ERR_INVALID_AUTH_CREDENTIALS,
13179 3,
13180 1,
13181 {TestRound(kConnect, kProxyChallenge, OK),
13182 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13183 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613184 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113185 {__LINE__,
13186 kProxy,
asankac93076192016-10-03 15:46:0213187 AUTH_ASYNC,
13188 OK,
13189 kSecureServer,
13190 AUTH_SYNC,
13191 OK,
13192 3,
13193 1,
13194 {TestRound(kConnect, kProxyChallenge, OK),
13195 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13196 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513197 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113198 {__LINE__,
13199 kProxy,
asankac93076192016-10-03 15:46:0213200 AUTH_ASYNC,
13201 OK,
13202 kSecureServer,
13203 AUTH_SYNC,
13204 ERR_INVALID_AUTH_CREDENTIALS,
13205 3,
13206 1,
13207 {TestRound(kConnect, kProxyChallenge, OK),
13208 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13209 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613210 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113211 {__LINE__,
13212 kProxy,
asankac93076192016-10-03 15:46:0213213 AUTH_SYNC,
13214 OK,
13215 kSecureServer,
13216 AUTH_ASYNC,
13217 OK,
13218 3,
13219 1,
13220 {TestRound(kConnect, kProxyChallenge, OK),
13221 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13222 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513223 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113224 {__LINE__,
13225 kProxy,
asankac93076192016-10-03 15:46:0213226 AUTH_SYNC,
13227 OK,
13228 kSecureServer,
13229 AUTH_ASYNC,
13230 ERR_INVALID_AUTH_CREDENTIALS,
13231 3,
13232 1,
13233 {TestRound(kConnect, kProxyChallenge, OK),
13234 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13235 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613236 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113237 {__LINE__,
13238 kProxy,
asankac93076192016-10-03 15:46:0213239 AUTH_ASYNC,
13240 OK,
13241 kSecureServer,
13242 AUTH_ASYNC,
13243 OK,
13244 3,
13245 1,
13246 {TestRound(kConnect, kProxyChallenge, OK),
13247 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13248 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513249 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113250 {__LINE__,
13251 kProxy,
asankac93076192016-10-03 15:46:0213252 AUTH_ASYNC,
13253 OK,
13254 kSecureServer,
13255 AUTH_ASYNC,
13256 ERR_INVALID_AUTH_CREDENTIALS,
13257 3,
13258 1,
13259 {TestRound(kConnect, kProxyChallenge, OK),
13260 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13261 &kServerChallenge),
asankae2257db2016-10-11 22:03:1613262 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113263 {__LINE__,
13264 kProxy,
13265 AUTH_ASYNC,
13266 ERR_INVALID_AUTH_CREDENTIALS,
13267 kSecureServer,
13268 AUTH_ASYNC,
13269 ERR_INVALID_AUTH_CREDENTIALS,
13270 4,
13271 2,
13272 {TestRound(kConnect, kProxyChallenge, OK),
13273 TestRound(kConnect, kProxyChallenge, OK),
13274 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
13275 &kServerChallenge),
13276 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1513277 };
13278
asanka463ca4262016-11-16 02:34:3113279 for (const auto& test_config : test_configs) {
13280 SCOPED_TRACE(::testing::Message() << "Test config at "
13281 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0813282 HttpAuthHandlerMock::Factory* auth_factory(
13283 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713284 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4913285 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2613286
13287 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1513288 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3113289 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0813290 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13291 std::string auth_challenge = "Mock realm=proxy";
13292 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2413293 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13294 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0813295 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2013296 empty_ssl_info, origin,
13297 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813298 auth_handler->SetGenerateExpectation(
13299 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113300 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0813301 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
13302 }
[email protected]044de0642010-06-17 10:42:1513303 }
13304 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0013305 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1513306 std::string auth_challenge = "Mock realm=server";
13307 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2413308 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13309 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1513310 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013311 empty_ssl_info, origin,
13312 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513313 auth_handler->SetGenerateExpectation(
13314 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3113315 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0813316 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1613317
13318 // The second handler always succeeds. It should only be used where there
13319 // are multiple auth sessions for server auth in the same network
13320 // transaction using the same auth scheme.
13321 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1913322 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1613323 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
13324 empty_ssl_info, origin,
13325 NetLogWithSource());
13326 second_handler->SetGenerateExpectation(true, OK);
13327 auth_factory->AddMockHandler(second_handler.release(),
13328 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1513329 }
13330 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5913331 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913332 ProxyResolutionService::CreateFixed(test_config.proxy_url,
13333 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1513334 } else {
Bence Béky53a5aef2018-03-29 21:54:1213335 session_deps_.proxy_resolution_service =
13336 ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1513337 }
13338
13339 HttpRequestInfo request;
13340 request.method = "GET";
13341 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e2018-02-07 07:41:1013342 request.traffic_annotation =
13343 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1513344
danakj1fd259a02016-04-16 03:17:0913345 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1513346
rchcb68dc62015-05-21 04:45:3613347 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
13348
13349 std::vector<std::vector<MockRead>> mock_reads(1);
13350 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1513351 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213352 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1513353 const TestRound& read_write_round = test_config.rounds[round];
13354
13355 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3613356 mock_reads.back().push_back(read_write_round.read);
13357 mock_writes.back().push_back(read_write_round.write);
13358
13359 // kProxyChallenge uses Proxy-Connection: close which means that the
13360 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5413361 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3613362 mock_reads.push_back(std::vector<MockRead>());
13363 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1513364 }
13365
rchcb68dc62015-05-21 04:45:3613366 if (read_write_round.extra_read) {
13367 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1513368 }
rchcb68dc62015-05-21 04:45:3613369 if (read_write_round.extra_write) {
13370 mock_writes.back().push_back(*read_write_round.extra_write);
13371 }
[email protected]044de0642010-06-17 10:42:1513372
13373 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1513374 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0713375 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1513376 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3613377 }
[email protected]044de0642010-06-17 10:42:1513378
danakj1fd259a02016-04-16 03:17:0913379 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3613380 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1913381 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:0113382 mock_reads[i], mock_writes[i]));
rchcb68dc62015-05-21 04:45:3613383 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3213384 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3613385 }
13386
mmenkecc2298e2015-12-07 18:20:1813387 // Transaction must be created after DataProviders, so it's destroyed before
13388 // they are as well.
13389 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13390
rchcb68dc62015-05-21 04:45:3613391 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2213392 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3613393 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1513394 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4113395 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1513396 int rv;
13397 if (round == 0) {
tfarina42834112016-09-22 13:38:2013398 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1513399 } else {
[email protected]49639fa2011-12-20 23:22:4113400 rv = trans.RestartWithAuth(
13401 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1513402 }
13403 if (rv == ERR_IO_PENDING)
13404 rv = callback.WaitForResult();
13405
13406 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1613407 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5013408 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5513409 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1513410 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
13411 continue;
13412 }
13413 if (round + 1 < test_config.num_auth_rounds) {
wezca1070932016-05-26 20:30:5213414 EXPECT_TRUE(response->auth_challenge);
[email protected]044de0642010-06-17 10:42:1513415 } else {
wezca1070932016-05-26 20:30:5213416 EXPECT_FALSE(response->auth_challenge);
asankae2257db2016-10-11 22:03:1613417 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1513418 }
13419 }
[email protected]e5ae96a2010-04-14 20:12:4513420 }
13421}
13422
bncd16676a2016-07-20 16:23:0113423TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1413424 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1413425 HttpAuthHandlerMock::Factory* auth_factory(
13426 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0713427 session_deps_.http_auth_handler_factory.reset(auth_factory);
Bence Béky53a5aef2018-03-29 21:54:1213428 session_deps_.proxy_resolution_service =
13429 ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0713430 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
[email protected]c871bce92010-07-15 21:51:1413431
13432 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
13433 auth_handler->set_connection_based(true);
13434 std::string auth_challenge = "Mock realm=server";
13435 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2413436 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
13437 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4913438 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1413439 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2013440 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0813441 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1413442
[email protected]c871bce92010-07-15 21:51:1413443 int rv = OK;
13444 const HttpResponseInfo* response = NULL;
13445 HttpRequestInfo request;
13446 request.method = "GET";
13447 request.url = origin;
Ramin Halavatib5e433e2018-02-07 07:41:1013448 request.traffic_annotation =
13449 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2713450
danakj1fd259a02016-04-16 03:17:0913451 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1013452
13453 // Use a TCP Socket Pool with only one connection per group. This is used
13454 // to validate that the TCP socket is not released to the pool between
13455 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4213456 HttpNetworkSessionPeer session_peer(session.get());
[email protected]ab739042011-04-07 15:22:2813457 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
[email protected]7ef4cbbb2011-02-06 11:19:1013458 50, // Max sockets for pool
13459 1, // Max sockets per group
tbansal7b403bcc2016-04-13 22:33:2113460 session_deps_.host_resolver.get(), session_deps_.socket_factory.get(),
13461 NULL, session_deps_.net_log);
Jeremy Roman0579ed62017-08-29 15:56:1913462 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
[email protected]a42dbd142011-11-17 16:42:0213463 mock_pool_manager->SetTransportSocketPool(transport_pool);
dchengc7eeda422015-12-26 03:56:4813464 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1013465
bnc691fda62016-08-12 00:43:1613466 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113467 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1413468
13469 const MockWrite kGet(
13470 "GET / HTTP/1.1\r\n"
13471 "Host: www.example.com\r\n"
13472 "Connection: keep-alive\r\n\r\n");
13473 const MockWrite kGetAuth(
13474 "GET / HTTP/1.1\r\n"
13475 "Host: www.example.com\r\n"
13476 "Connection: keep-alive\r\n"
13477 "Authorization: auth_token\r\n\r\n");
13478
13479 const MockRead kServerChallenge(
13480 "HTTP/1.1 401 Unauthorized\r\n"
13481 "WWW-Authenticate: Mock realm=server\r\n"
13482 "Content-Type: text/html; charset=iso-8859-1\r\n"
13483 "Content-Length: 14\r\n\r\n"
13484 "Unauthorized\r\n");
13485 const MockRead kSuccess(
13486 "HTTP/1.1 200 OK\r\n"
13487 "Content-Type: text/html; charset=iso-8859-1\r\n"
13488 "Content-Length: 3\r\n\r\n"
13489 "Yes");
13490
13491 MockWrite writes[] = {
13492 // First round
13493 kGet,
13494 // Second round
13495 kGetAuth,
13496 // Third round
13497 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3013498 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1013499 kGetAuth,
13500 // Competing request
13501 kGet,
[email protected]c871bce92010-07-15 21:51:1413502 };
13503 MockRead reads[] = {
13504 // First round
13505 kServerChallenge,
13506 // Second round
13507 kServerChallenge,
13508 // Third round
[email protected]eca50e122010-09-11 14:03:3013509 kServerChallenge,
13510 // Fourth round
[email protected]c871bce92010-07-15 21:51:1413511 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1013512 // Competing response
13513 kSuccess,
[email protected]c871bce92010-07-15 21:51:1413514 };
Ryan Sleevib8d7ea02018-05-07 20:01:0113515 StaticSocketDataProvider data_provider(reads, writes);
[email protected]bb88e1d32013-05-03 23:11:0713516 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1413517
thestig9d3bb0c2015-01-24 00:49:5113518 const char kSocketGroup[] = "www.example.com:80";
[email protected]7ef4cbbb2011-02-06 11:19:1013519
13520 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1413521 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2013522 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1413523 if (rv == ERR_IO_PENDING)
13524 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113525 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613526 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213527 ASSERT_TRUE(response);
13528 EXPECT_TRUE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813529 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113530 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13531 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413532
[email protected]7ef4cbbb2011-02-06 11:19:1013533 // In between rounds, another request comes in for the same domain.
13534 // It should not be able to grab the TCP socket that trans has already
13535 // claimed.
bnc691fda62016-08-12 00:43:1613536 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4113537 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2013538 rv = trans_compete.Start(&request, callback_compete.callback(),
13539 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113540 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1013541 // callback_compete.WaitForResult at this point would stall forever,
13542 // since the HttpNetworkTransaction does not release the request back to
13543 // the pool until after authentication completes.
13544
13545 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1413546 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613547 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413548 if (rv == ERR_IO_PENDING)
13549 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113550 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613551 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213552 ASSERT_TRUE(response);
13553 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813554 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113555 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13556 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1413557
[email protected]7ef4cbbb2011-02-06 11:19:1013558 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1413559 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613560 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1413561 if (rv == ERR_IO_PENDING)
13562 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113563 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613564 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213565 ASSERT_TRUE(response);
13566 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813567 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3113568 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
13569 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3013570
[email protected]7ef4cbbb2011-02-06 11:19:1013571 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3013572 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1613573 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3013574 if (rv == ERR_IO_PENDING)
13575 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0113576 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613577 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213578 ASSERT_TRUE(response);
13579 EXPECT_FALSE(response->auth_challenge);
[email protected]ab739042011-04-07 15:22:2813580 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013581
asanka463ca4262016-11-16 02:34:3113582 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
13583 // auth handler should transition to a DONE state in concert with the remote
13584 // server. But that's not something we can test here with a mock handler.
13585 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
13586 auth_handler->state());
13587
[email protected]7ef4cbbb2011-02-06 11:19:1013588 // Read the body since the fourth round was successful. This will also
13589 // release the socket back to the pool.
Victor Costan9c7302b2018-08-27 16:39:4413590 scoped_refptr<IOBufferWithSize> io_buf =
13591 base::MakeRefCounted<IOBufferWithSize>(50);
bnc691fda62016-08-12 00:43:1613592 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013593 if (rv == ERR_IO_PENDING)
13594 rv = callback.WaitForResult();
13595 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613596 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013597 EXPECT_EQ(0, rv);
13598 // There are still 0 idle sockets, since the trans_compete transaction
13599 // will be handed it immediately after trans releases it to the group.
[email protected]ab739042011-04-07 15:22:2813600 EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1013601
13602 // The competing request can now finish. Wait for the headers and then
13603 // read the body.
13604 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0113605 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1613606 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013607 if (rv == ERR_IO_PENDING)
13608 rv = callback.WaitForResult();
13609 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1613610 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1013611 EXPECT_EQ(0, rv);
13612
13613 // Finally, the socket is released to the group.
[email protected]ab739042011-04-07 15:22:2813614 EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1413615}
13616
[email protected]65041fa2010-05-21 06:56:5313617// This tests the case that a request is issued via http instead of spdy after
13618// npn is negotiated.
bncd16676a2016-07-20 16:23:0113619TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5313620 HttpRequestInfo request;
13621 request.method = "GET";
bncce36dca22015-04-21 22:11:2313622 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013623 request.traffic_annotation =
13624 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5313625
13626 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2313627 MockWrite(
13628 "GET / HTTP/1.1\r\n"
13629 "Host: www.example.org\r\n"
13630 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5313631 };
13632
13633 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213634 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313635 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213636 MockRead("\r\n"),
13637 MockRead("hello world"),
13638 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5313639 };
13640
[email protected]8ddf8322012-02-23 18:08:0613641 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613642 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5313643
[email protected]bb88e1d32013-05-03 23:11:0713644 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5313645
Ryan Sleevib8d7ea02018-05-07 20:01:0113646 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0713647 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5313648
[email protected]49639fa2011-12-20 23:22:4113649 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5313650
danakj1fd259a02016-04-16 03:17:0913651 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613652 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5313653
tfarina42834112016-09-22 13:38:2013654 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5313655
robpercival214763f2016-07-01 23:27:0113656 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13657 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5313658
bnc691fda62016-08-12 00:43:1613659 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213660 ASSERT_TRUE(response);
13661 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5313662 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13663
13664 std::string response_data;
bnc691fda62016-08-12 00:43:1613665 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5313666 EXPECT_EQ("hello world", response_data);
13667
13668 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213669 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5313670}
[email protected]26ef6582010-06-24 02:30:4713671
bnc55ff9da2015-08-19 18:42:3513672// Simulate the SSL handshake completing with an NPN negotiation followed by an
13673// immediate server closing of the socket.
13674// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0113675TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4713676 HttpRequestInfo request;
13677 request.method = "GET";
bncce36dca22015-04-21 22:11:2313678 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013679 request.traffic_annotation =
13680 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4713681
[email protected]8ddf8322012-02-23 18:08:0613682 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613683 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0713684 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4713685
Ryan Hamilton0239aac2018-05-19 00:03:1313686 spdy::SpdySerializedFrame req(
13687 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113688 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4713689
13690 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613691 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4713692 };
13693
Ryan Sleevib8d7ea02018-05-07 20:01:0113694 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713695 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4713696
[email protected]49639fa2011-12-20 23:22:4113697 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4713698
danakj1fd259a02016-04-16 03:17:0913699 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1613700 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4713701
tfarina42834112016-09-22 13:38:2013702 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113703 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13704 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4713705}
[email protected]65d34382010-07-01 18:12:2613706
[email protected]795cbf82013-07-22 09:37:2713707// A subclass of HttpAuthHandlerMock that records the request URL when
13708// it gets it. This is needed since the auth handler may get destroyed
13709// before we get a chance to query it.
13710class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
13711 public:
13712 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
13713
Chris Watkins7a41d3552017-12-01 02:13:2713714 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2713715
13716 protected:
dchengb03027d2014-10-21 12:00:2013717 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
13718 const HttpRequestInfo* request,
Bence Béky7236fb72018-08-01 14:35:0913719 CompletionOnceCallback callback,
dchengb03027d2014-10-21 12:00:2013720 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2713721 *url_ = request->url;
13722 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
Bence Béky7236fb72018-08-01 14:35:0913723 credentials, request, std::move(callback), auth_token);
[email protected]795cbf82013-07-22 09:37:2713724 }
13725
13726 private:
13727 GURL* url_;
13728};
13729
[email protected]8e6441ca2010-08-19 05:56:3813730// Test that if we cancel the transaction as the connection is completing, that
13731// everything tears down correctly.
bncd16676a2016-07-20 16:23:0113732TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3813733 // Setup everything about the connection to complete synchronously, so that
13734 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
13735 // for is the callback from the HttpStreamRequest.
13736 // Then cancel the transaction.
13737 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3613738 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3813739 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0613740 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
13741 MockRead(SYNCHRONOUS, "hello world"),
13742 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3813743 };
13744
[email protected]8e6441ca2010-08-19 05:56:3813745 HttpRequestInfo request;
13746 request.method = "GET";
bncce36dca22015-04-21 22:11:2313747 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013748 request.traffic_annotation =
13749 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3813750
danakj1fd259a02016-04-16 03:17:0913751 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813752 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913753 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2713754
Ryan Sleevib8d7ea02018-05-07 20:01:0113755 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]8e6441ca2010-08-19 05:56:3813756 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0713757 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3813758
[email protected]49639fa2011-12-20 23:22:4113759 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3813760
vishal.b62985ca92015-04-17 08:45:5113761 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4113762 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113763 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3813764 trans.reset(); // Cancel the transaction here.
13765
fdoray92e35a72016-06-10 15:54:5513766 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3013767}
13768
[email protected]ecab6e052014-05-16 14:58:1213769// Test that if a transaction is cancelled after receiving the headers, the
13770// stream is drained properly and added back to the socket pool. The main
13771// purpose of this test is to make sure that an HttpStreamParser can be read
13772// from after the HttpNetworkTransaction and the objects it owns have been
13773// deleted.
13774// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0113775TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1213776 MockRead data_reads[] = {
13777 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
13778 MockRead(ASYNC, "Content-Length: 2\r\n"),
13779 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
13780 MockRead(ASYNC, "1"),
13781 // 2 async reads are necessary to trigger a ReadResponseBody call after the
13782 // HttpNetworkTransaction has been deleted.
13783 MockRead(ASYNC, "2"),
13784 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
13785 };
Ryan Sleevib8d7ea02018-05-07 20:01:0113786 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]ecab6e052014-05-16 14:58:1213787 session_deps_.socket_factory->AddSocketDataProvider(&data);
13788
danakj1fd259a02016-04-16 03:17:0913789 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1213790
13791 {
13792 HttpRequestInfo request;
13793 request.method = "GET";
bncce36dca22015-04-21 22:11:2313794 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013795 request.traffic_annotation =
13796 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1213797
dcheng48459ac22014-08-26 00:46:4113798 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1213799 TestCompletionCallback callback;
13800
tfarina42834112016-09-22 13:38:2013801 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113802 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1213803 callback.WaitForResult();
13804
13805 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213806 ASSERT_TRUE(response);
13807 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1213808 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13809
13810 // The transaction and HttpRequestInfo are deleted.
13811 }
13812
13813 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5513814 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1213815
13816 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4113817 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1213818}
13819
[email protected]76a505b2010-08-25 06:23:0013820// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0113821TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913822 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913823 ProxyResolutionService::CreateFixedFromPacResult(
13824 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5113825 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713826 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913827 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013828
[email protected]76a505b2010-08-25 06:23:0013829 HttpRequestInfo request;
13830 request.method = "GET";
bncce36dca22015-04-21 22:11:2313831 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013832 request.traffic_annotation =
13833 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013834
13835 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2313836 MockWrite(
13837 "GET http://www.example.org/ HTTP/1.1\r\n"
13838 "Host: www.example.org\r\n"
13839 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013840 };
13841
13842 MockRead data_reads1[] = {
13843 MockRead("HTTP/1.1 200 OK\r\n"),
13844 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13845 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613846 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013847 };
13848
Ryan Sleevib8d7ea02018-05-07 20:01:0113849 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0713850 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0013851
[email protected]49639fa2011-12-20 23:22:4113852 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013853
bnc691fda62016-08-12 00:43:1613854 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913855 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613856 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913857 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13858 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013859
bnc691fda62016-08-12 00:43:1613860 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113861 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013862
13863 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113864 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0013865
bnc691fda62016-08-12 00:43:1613866 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213867 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013868
13869 EXPECT_TRUE(response->headers->IsKeepAlive());
13870 EXPECT_EQ(200, response->headers->response_code());
13871 EXPECT_EQ(100, response->headers->GetContentLength());
13872 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713873 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13874 HostPortPair::FromString("myproxy:70")),
13875 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913876 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13877 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13878 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0013879 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2013880
13881 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613882 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013883 TestLoadTimingNotReusedWithPac(load_timing_info,
13884 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0013885}
13886
13887// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0113888TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5913889 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913890 ProxyResolutionService::CreateFixedFromPacResult(
13891 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5113892 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0713893 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913894 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0013895
[email protected]76a505b2010-08-25 06:23:0013896 HttpRequestInfo request;
13897 request.method = "GET";
bncce36dca22015-04-21 22:11:2313898 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1013899 request.traffic_annotation =
13900 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0013901
13902 // Since we have proxy, should try to establish tunnel.
13903 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1713904 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
13905 "Host: www.example.org:443\r\n"
13906 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013907
rsleevidb16bb02015-11-12 23:47:1713908 MockWrite("GET / HTTP/1.1\r\n"
13909 "Host: www.example.org\r\n"
13910 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0013911 };
13912
13913 MockRead data_reads1[] = {
13914 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
13915
13916 MockRead("HTTP/1.1 200 OK\r\n"),
13917 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
13918 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0613919 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0013920 };
13921
Ryan Sleevib8d7ea02018-05-07 20:01:0113922 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0713923 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0613924 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0713925 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0013926
[email protected]49639fa2011-12-20 23:22:4113927 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0013928
bnc691fda62016-08-12 00:43:1613929 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0913930 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1613931 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0913932 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
13933 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5013934
bnc691fda62016-08-12 00:43:1613935 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0113936 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0013937
13938 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0113939 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4613940 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4013941 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0013942 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0013943 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
13944 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013945 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4013946 entries, pos,
mikecirone8b85c432016-09-08 19:11:0013947 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
13948 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0013949
bnc691fda62016-08-12 00:43:1613950 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5213951 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0013952
13953 EXPECT_TRUE(response->headers->IsKeepAlive());
13954 EXPECT_EQ(200, response->headers->response_code());
13955 EXPECT_EQ(100, response->headers->GetContentLength());
13956 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
13957 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4713958 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
13959 HostPortPair::FromString("myproxy:70")),
13960 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0913961 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
13962 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
13963 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2013964
13965 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1613966 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2013967 TestLoadTimingNotReusedWithPac(load_timing_info,
13968 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0013969}
13970
rsleevidb16bb02015-11-12 23:47:1713971// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
13972// literal host.
bncd16676a2016-07-20 16:23:0113973TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5913974 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4913975 ProxyResolutionService::CreateFixedFromPacResult(
13976 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1713977 BoundTestNetLog log;
13978 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0913979 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1713980
13981 HttpRequestInfo request;
13982 request.method = "GET";
Eric Romanda790f92018-11-07 19:17:1513983 request.url = GURL("https://[::2]:443/");
Ramin Halavatib5e433e2018-02-07 07:41:1013984 request.traffic_annotation =
13985 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1713986
13987 // Since we have proxy, should try to establish tunnel.
13988 MockWrite data_writes1[] = {
Eric Romanda790f92018-11-07 19:17:1513989 MockWrite("CONNECT [::2]:443 HTTP/1.1\r\n"
13990 "Host: [::2]:443\r\n"
rsleevidb16bb02015-11-12 23:47:1713991 "Proxy-Connection: keep-alive\r\n\r\n"),
13992
13993 MockWrite("GET / HTTP/1.1\r\n"
Eric Romanda790f92018-11-07 19:17:1513994 "Host: [::2]\r\n"
rsleevidb16bb02015-11-12 23:47:1713995 "Connection: keep-alive\r\n\r\n"),
13996 };
13997
13998 MockRead data_reads1[] = {
13999 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14000
14001 MockRead("HTTP/1.1 200 OK\r\n"),
14002 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14003 MockRead("Content-Length: 100\r\n\r\n"),
14004 MockRead(SYNCHRONOUS, OK),
14005 };
14006
Ryan Sleevib8d7ea02018-05-07 20:01:0114007 StaticSocketDataProvider data1(data_reads1, data_writes1);
rsleevidb16bb02015-11-12 23:47:1714008 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14009 SSLSocketDataProvider ssl(ASYNC, OK);
14010 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14011
14012 TestCompletionCallback callback1;
14013
bnc691fda62016-08-12 00:43:1614014 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1714015
bnc691fda62016-08-12 00:43:1614016 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114017 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1714018
14019 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114020 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1714021 TestNetLogEntry::List entries;
14022 log.GetEntries(&entries);
14023 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014024 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14025 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714026 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014027 entries, pos,
14028 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14029 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714030
bnc691fda62016-08-12 00:43:1614031 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214032 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1714033
14034 EXPECT_TRUE(response->headers->IsKeepAlive());
14035 EXPECT_EQ(200, response->headers->response_code());
14036 EXPECT_EQ(100, response->headers->GetContentLength());
14037 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14038 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714039 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14040 HostPortPair::FromString("myproxy:70")),
14041 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1714042
14043 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614044 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1714045 TestLoadTimingNotReusedWithPac(load_timing_info,
14046 CONNECT_TIMING_HAS_SSL_TIMES);
14047}
14048
[email protected]76a505b2010-08-25 06:23:0014049// Test a basic HTTPS GET request through a proxy, but the server hangs up
14050// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0114051TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Ramin Halavatica8d5252018-03-12 05:33:4914052 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14053 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114054 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714055 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914056 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014057
[email protected]76a505b2010-08-25 06:23:0014058 HttpRequestInfo request;
14059 request.method = "GET";
bncce36dca22015-04-21 22:11:2314060 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014061 request.traffic_annotation =
14062 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014063
14064 // Since we have proxy, should try to establish tunnel.
14065 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714066 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14067 "Host: www.example.org:443\r\n"
14068 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014069
rsleevidb16bb02015-11-12 23:47:1714070 MockWrite("GET / HTTP/1.1\r\n"
14071 "Host: www.example.org\r\n"
14072 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014073 };
14074
14075 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0014076 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614077 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0014078 };
14079
Ryan Sleevib8d7ea02018-05-07 20:01:0114080 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714081 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614082 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714083 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014084
[email protected]49639fa2011-12-20 23:22:4114085 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014086
bnc691fda62016-08-12 00:43:1614087 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5014088
bnc691fda62016-08-12 00:43:1614089 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114090 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014091
14092 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114093 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4614094 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014095 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014096 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014097 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14098 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014099 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014100 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014101 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14102 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014103}
14104
[email protected]749eefa82010-09-13 22:14:0314105// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0114106TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
Ryan Hamilton0239aac2018-05-19 00:03:1314107 spdy::SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4914108 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114109 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0314110
Ryan Hamilton0239aac2018-05-19 00:03:1314111 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
14112 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0314113 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114114 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0314115 };
14116
Ryan Sleevib8d7ea02018-05-07 20:01:0114117 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714118 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0314119
[email protected]8ddf8322012-02-23 18:08:0614120 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614121 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714122 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0314123
danakj1fd259a02016-04-16 03:17:0914124 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0314125
14126 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2314127 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4014128 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Paul Jensena457017a2018-01-19 23:52:0414129 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]795cbf82013-07-22 09:37:2714130 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5214131 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0314132
14133 HttpRequestInfo request;
14134 request.method = "GET";
bncce36dca22015-04-21 22:11:2314135 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1014136 request.traffic_annotation =
14137 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0314138
bnc691fda62016-08-12 00:43:1614139 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0314140
[email protected]41d64e82013-07-03 22:44:2614141 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014142 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114143 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14144 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0314145}
14146
[email protected]73b8dd222010-11-11 19:55:2414147// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1614148// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0214149void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0714150 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2914151 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714152 request_info.url = GURL("https://www.example.com/");
14153 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914154 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014155 request_info.traffic_annotation =
14156 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714157
[email protected]8ddf8322012-02-23 18:08:0614158 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2914159 MockWrite data_writes[] = {
14160 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2414161 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114162 StaticSocketDataProvider data(base::span<MockRead>(), data_writes);
[email protected]bb88e1d32013-05-03 23:11:0714163 session_deps_.socket_factory->AddSocketDataProvider(&data);
14164 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2414165
danakj1fd259a02016-04-16 03:17:0914166 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614167 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2414168
[email protected]49639fa2011-12-20 23:22:4114169 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014170 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2914171 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2414172 rv = callback.WaitForResult();
14173 ASSERT_EQ(error, rv);
14174}
14175
bncd16676a2016-07-20 16:23:0114176TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2414177 // Just check a grab bag of cert errors.
14178 static const int kErrors[] = {
14179 ERR_CERT_COMMON_NAME_INVALID,
14180 ERR_CERT_AUTHORITY_INVALID,
14181 ERR_CERT_DATE_INVALID,
14182 };
14183 for (size_t i = 0; i < arraysize(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0614184 CheckErrorIsPassedBack(kErrors[i], ASYNC);
14185 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2414186 }
14187}
14188
[email protected]bd0b6772011-01-11 19:59:3014189// Ensure that a client certificate is removed from the SSL client auth
14190// cache when:
14191// 1) No proxy is involved.
14192// 2) TLS False Start is disabled.
14193// 3) The initial TLS handshake requests a client certificate.
14194// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114195TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914196 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714197 request_info.url = GURL("https://www.example.com/");
14198 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914199 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014200 request_info.traffic_annotation =
14201 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714202
[email protected]bd0b6772011-01-11 19:59:3014203 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114204 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014205
14206 // [ssl_]data1 contains the data for the first SSL handshake. When a
14207 // CertificateRequest is received for the first time, the handshake will
14208 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2914209 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014210 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714211 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0114212 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0714213 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014214
14215 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
14216 // False Start is not being used, the result of the SSL handshake will be
14217 // returned as part of the SSLClientSocket::Connect() call. This test
14218 // matches the result of a server sending a handshake_failure alert,
14219 // rather than a Finished message, because it requires a client
14220 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2914221 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014222 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714223 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0114224 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0714225 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014226
14227 // [ssl_]data3 contains the data for the third SSL handshake. When a
14228 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214229 // HttpNetworkTransaction will attempt to fallback to TLSv1.1 if the previous
14230 // connection was attempted with TLSv1.2. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3014231 // of the HttpNetworkTransaction. Because this test failure is due to
14232 // requiring a client certificate, this fallback handshake should also
14233 // fail.
ttuttle859dc7a2015-04-23 19:42:2914234 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3014235 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714236 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0114237 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0714238 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014239
[email protected]80c75f682012-05-26 16:22:1714240 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
14241 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4214242 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
14243 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1714244 // of the HttpNetworkTransaction. Because this test failure is due to
14245 // requiring a client certificate, this fallback handshake should also
14246 // fail.
ttuttle859dc7a2015-04-23 19:42:2914247 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1714248 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714249 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0114250 StaticSocketDataProvider data4;
[email protected]bb88e1d32013-05-03 23:11:0714251 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714252
danakj1fd259a02016-04-16 03:17:0914253 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614254 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014255
[email protected]bd0b6772011-01-11 19:59:3014256 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4114257 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014258 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114259 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014260
14261 // Complete the SSL handshake, which should abort due to requiring a
14262 // client certificate.
14263 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114264 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014265
14266 // Indicate that no certificate should be supplied. From the perspective
14267 // of SSLClientCertCache, NULL is just as meaningful as a real
14268 // certificate, so this is the same as supply a
14269 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614270 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114271 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014272
14273 // Ensure the certificate was added to the client auth cache before
14274 // allowing the connection to continue restarting.
14275 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414276 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114277 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414278 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214279 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014280
14281 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714282 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14283 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014284 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114285 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014286
14287 // Ensure that the client certificate is removed from the cache on a
14288 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114289 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414290 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014291}
14292
14293// Ensure that a client certificate is removed from the SSL client auth
14294// cache when:
14295// 1) No proxy is involved.
14296// 2) TLS False Start is enabled.
14297// 3) The initial TLS handshake requests a client certificate.
14298// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0114299TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2914300 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2714301 request_info.url = GURL("https://www.example.com/");
14302 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914303 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014304 request_info.traffic_annotation =
14305 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714306
[email protected]bd0b6772011-01-11 19:59:3014307 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114308 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3014309
14310 // When TLS False Start is used, SSLClientSocket::Connect() calls will
14311 // return successfully after reading up to the peer's Certificate message.
14312 // This is to allow the caller to call SSLClientSocket::Write(), which can
14313 // enqueue application data to be sent in the same packet as the
14314 // ChangeCipherSpec and Finished messages.
14315 // The actual handshake will be finished when SSLClientSocket::Read() is
14316 // called, which expects to process the peer's ChangeCipherSpec and
14317 // Finished messages. If there was an error negotiating with the peer,
14318 // such as due to the peer requiring a client certificate when none was
14319 // supplied, the alert sent by the peer won't be processed until Read() is
14320 // called.
14321
14322 // Like the non-False Start case, when a client certificate is requested by
14323 // the peer, the handshake is aborted during the Connect() call.
14324 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2914325 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3014326 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714327 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0114328 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0714329 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3014330
14331 // When a client certificate is supplied, Connect() will not be aborted
14332 // when the peer requests the certificate. Instead, the handshake will
14333 // artificially succeed, allowing the caller to write the HTTP request to
14334 // the socket. The handshake messages are not processed until Read() is
14335 // called, which then detects that the handshake was aborted, due to the
14336 // peer sending a handshake_failure because it requires a client
14337 // certificate.
ttuttle859dc7a2015-04-23 19:42:2914338 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014339 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714340 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2914341 MockRead data2_reads[] = {
14342 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3014343 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114344 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0714345 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3014346
14347 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1714348 // the data for the SSL handshake once the TLSv1.1 connection falls back to
14349 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914350 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3014351 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714352 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0114353 StaticSocketDataProvider data3(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0714354 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3014355
[email protected]80c75f682012-05-26 16:22:1714356 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
14357 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2914358 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1714359 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714360 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0114361 StaticSocketDataProvider data4(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0714362 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1714363
[email protected]7799de12013-05-30 05:52:5114364 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2914365 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5114366 ssl_data5.cert_request_info = cert_request.get();
14367 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
Ryan Sleevib8d7ea02018-05-07 20:01:0114368 StaticSocketDataProvider data5(data2_reads, base::span<MockWrite>());
[email protected]7799de12013-05-30 05:52:5114369 session_deps_.socket_factory->AddSocketDataProvider(&data5);
14370
danakj1fd259a02016-04-16 03:17:0914371 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614372 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3014373
[email protected]bd0b6772011-01-11 19:59:3014374 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4114375 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014376 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114377 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014378
14379 // Complete the SSL handshake, which should abort due to requiring a
14380 // client certificate.
14381 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114382 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3014383
14384 // Indicate that no certificate should be supplied. From the perspective
14385 // of SSLClientCertCache, NULL is just as meaningful as a real
14386 // certificate, so this is the same as supply a
14387 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614388 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114389 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3014390
14391 // Ensure the certificate was added to the client auth cache before
14392 // allowing the connection to continue restarting.
14393 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414394 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114395 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414396 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214397 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3014398
[email protected]bd0b6772011-01-11 19:59:3014399 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1714400 // then consume ssl_data3 and ssl_data4, both of which should also fail.
14401 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3014402 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114403 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3014404
14405 // Ensure that the client certificate is removed from the cache on a
14406 // handshake failure.
[email protected]791879c2013-12-17 07:22:4114407 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414408 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3014409}
14410
[email protected]8c405132011-01-11 22:03:1814411// Ensure that a client certificate is removed from the SSL client auth
14412// cache when:
14413// 1) An HTTPS proxy is involved.
14414// 3) The HTTPS proxy requests a client certificate.
14415// 4) The client supplies an invalid/unacceptable certificate for the
14416// proxy.
14417// The test is repeated twice, first for connecting to an HTTPS endpoint,
14418// then for connecting to an HTTP endpoint.
bncd16676a2016-07-20 16:23:0114419TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Ramin Halavatica8d5252018-03-12 05:33:4914420 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14421 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114422 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714423 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1814424
14425 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4114426 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1814427
14428 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
14429 // [ssl_]data[1-3]. Rather than represending the endpoint
14430 // (www.example.com:443), they represent failures with the HTTPS proxy
14431 // (proxy:70).
ttuttle859dc7a2015-04-23 19:42:2914432 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]8c405132011-01-11 22:03:1814433 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714434 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0114435 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0714436 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1814437
ttuttle859dc7a2015-04-23 19:42:2914438 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814439 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714440 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0114441 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0714442 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8c405132011-01-11 22:03:1814443
[email protected]80c75f682012-05-26 16:22:1714444 // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
14445#if 0
ttuttle859dc7a2015-04-23 19:42:2914446 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]8c405132011-01-11 22:03:1814447 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0714448 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0114449 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0714450 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]80c75f682012-05-26 16:22:1714451#endif
[email protected]8c405132011-01-11 22:03:1814452
ttuttle859dc7a2015-04-23 19:42:2914453 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1814454 requests[0].url = GURL("https://www.example.com/");
14455 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914456 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014457 requests[0].traffic_annotation =
14458 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814459
14460 requests[1].url = GURL("http://www.example.com/");
14461 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2914462 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e2018-02-07 07:41:1014463 requests[1].traffic_annotation =
14464 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1814465
14466 for (size_t i = 0; i < arraysize(requests); ++i) {
[email protected]bb88e1d32013-05-03 23:11:0714467 session_deps_.socket_factory->ResetNextMockIndexes();
danakj1fd259a02016-04-16 03:17:0914468 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614469 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]8c405132011-01-11 22:03:1814470
14471 // Begin the SSL handshake with the proxy.
[email protected]49639fa2011-12-20 23:22:4114472 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2014473 int rv = trans.Start(&requests[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114474 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814475
14476 // Complete the SSL handshake, which should abort due to requiring a
14477 // client certificate.
14478 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114479 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]8c405132011-01-11 22:03:1814480
14481 // Indicate that no certificate should be supplied. From the perspective
14482 // of SSLClientCertCache, NULL is just as meaningful as a real
14483 // certificate, so this is the same as supply a
14484 // legitimate-but-unacceptable certificate.
bnc691fda62016-08-12 00:43:1614485 rv = trans.RestartWithCertificate(NULL, NULL, callback.callback());
robpercival214763f2016-07-01 23:27:0114486 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c405132011-01-11 22:03:1814487
14488 // Ensure the certificate was added to the client auth cache before
14489 // allowing the connection to continue restarting.
14490 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5414491 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4114492 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414493 HostPortPair("proxy", 70), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5214494 ASSERT_FALSE(client_cert);
[email protected]8c405132011-01-11 22:03:1814495 // Ensure the certificate was NOT cached for the endpoint. This only
14496 // applies to HTTPS requests, but is fine to check for HTTP requests.
[email protected]791879c2013-12-17 07:22:4114497 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414498 HostPortPair("www.example.com", 443), &client_cert,
14499 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814500
14501 // Restart the handshake. This will consume ssl_data2, which fails, and
14502 // then consume ssl_data3, which should also fail. The result code is
14503 // checked against what ssl_data3 should return.
14504 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114505 ASSERT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]8c405132011-01-11 22:03:1814506
14507 // Now that the new handshake has failed, ensure that the client
14508 // certificate was removed from the client auth cache.
[email protected]791879c2013-12-17 07:22:4114509 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414510 HostPortPair("proxy", 70), &client_cert, &client_private_key));
[email protected]791879c2013-12-17 07:22:4114511 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5414512 HostPortPair("www.example.com", 443), &client_cert,
14513 &client_private_key));
[email protected]8c405132011-01-11 22:03:1814514 }
14515}
14516
bncd16676a2016-07-20 16:23:0114517TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4614518 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914519 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914520 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614521
bnc032658ba2016-09-26 18:17:1514522 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614523
Ryan Hamilton0239aac2018-05-19 00:03:1314524 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914525 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814526 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1314527 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714528 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614529 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114530 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614531 };
Ryan Hamilton0239aac2018-05-19 00:03:1314532 spdy::SpdySerializedFrame host1_resp(
14533 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
14534 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4114535 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1314536 spdy::SpdySerializedFrame host2_resp(
14537 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
14538 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4114539 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614540 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114541 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14542 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314543 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614544 };
14545
eroman36d84e54432016-03-17 03:23:0214546 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214547 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114548 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714549 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4614550
[email protected]aa22b242011-11-16 18:58:2914551 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4614552 HttpRequestInfo request1;
14553 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314554 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4614555 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014556 request1.traffic_annotation =
14557 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014558 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614559
tfarina42834112016-09-22 13:38:2014560 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114561 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14562 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614563
14564 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214565 ASSERT_TRUE(response);
14566 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214567 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614568
14569 std::string response_data;
robpercival214763f2016-07-01 23:27:0114570 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614571 EXPECT_EQ("hello!", response_data);
14572
bnca4d611d2016-09-22 19:55:3714573 // Preload mail.example.com into HostCache.
14574 HostPortPair host_port("mail.example.com", 443);
[email protected]5109c1952013-08-20 18:44:1014575 HostResolver::RequestInfo resolve_info(host_port);
[email protected]e3ceb682011-06-28 23:55:4614576 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1014577 std::unique_ptr<HostResolver::Request> request;
14578 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14579 &ignored, callback.callback(),
tfarina42834112016-09-22 13:38:2014580 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114581 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4714582 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114583 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4614584
14585 HttpRequestInfo request2;
14586 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714587 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4614588 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014589 request2.traffic_annotation =
14590 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014591 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4614592
tfarina42834112016-09-22 13:38:2014593 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114594 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14595 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614596
14597 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214598 ASSERT_TRUE(response);
14599 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214600 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4614601 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214602 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114603 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4614604 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4614605}
14606
bncd16676a2016-07-20 16:23:0114607TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0214608 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914609 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0914610 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0214611
bnc032658ba2016-09-26 18:17:1514612 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0214613
Ryan Hamilton0239aac2018-05-19 00:03:1314614 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914615 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814616 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1314617 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714618 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0214619 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114620 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0214621 };
Ryan Hamilton0239aac2018-05-19 00:03:1314622 spdy::SpdySerializedFrame host1_resp(
14623 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
14624 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4114625 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1314626 spdy::SpdySerializedFrame host2_resp(
14627 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
14628 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4114629 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0214630 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114631 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14632 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314633 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0214634 };
14635
eroman36d84e54432016-03-17 03:23:0214636 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214637 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114638 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714639 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0214640
14641 TestCompletionCallback callback;
14642 HttpRequestInfo request1;
14643 request1.method = "GET";
bncce36dca22015-04-21 22:11:2314644 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0214645 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014646 request1.traffic_annotation =
14647 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014648 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214649
tfarina42834112016-09-22 13:38:2014650 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114651 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14652 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214653
14654 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5214655 ASSERT_TRUE(response);
14656 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214657 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214658
14659 std::string response_data;
robpercival214763f2016-07-01 23:27:0114660 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214661 EXPECT_EQ("hello!", response_data);
14662
14663 HttpRequestInfo request2;
14664 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3714665 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0214666 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014667 request2.traffic_annotation =
14668 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5014669 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0214670
tfarina42834112016-09-22 13:38:2014671 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114672 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14673 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214674
14675 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5214676 ASSERT_TRUE(response);
14677 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0214678 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0214679 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214680 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0114681 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0214682 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0214683}
14684
bnc8016c1f2017-03-31 02:11:2914685// Regression test for https://crbug.com/546991.
14686// The server might not be able to serve an IP pooled request, and might send a
14687// 421 Misdirected Request response status to indicate this.
14688// HttpNetworkTransaction should reset the request and retry without IP pooling.
14689TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
14690 // Two hosts resolve to the same IP address.
14691 const std::string ip_addr = "1.2.3.4";
14692 IPAddress ip;
14693 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14694 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14695
Jeremy Roman0579ed62017-08-29 15:56:1914696 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2914697 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14698 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14699
14700 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14701
14702 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1314703 spdy::SpdySerializedFrame req1(
bnc8016c1f2017-03-31 02:11:2914704 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14705 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1314706 spdy::SpdySerializedFrame req2(
bnc8016c1f2017-03-31 02:11:2914707 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1314708 spdy::SpdySerializedFrame rst(
14709 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
bnc8016c1f2017-03-31 02:11:2914710 MockWrite writes1[] = {
14711 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14712 CreateMockWrite(rst, 6),
14713 };
14714
14715 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1314716 spdy::SpdySerializedFrame resp1(
14717 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14718 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14719 spdy::SpdyHeaderBlock response_headers;
14720 response_headers[spdy::kHttp2StatusHeader] = "421";
14721 spdy::SpdySerializedFrame resp2(
bnc8016c1f2017-03-31 02:11:2914722 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
14723 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14724 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14725
14726 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114727 SequencedSocketData data1(connect1, reads1, writes1);
bnc8016c1f2017-03-31 02:11:2914728 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14729
14730 AddSSLSocketData();
14731
14732 // Retry the second request on a second connection.
14733 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1314734 spdy::SpdySerializedFrame req3(
bnc8016c1f2017-03-31 02:11:2914735 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14736 MockWrite writes2[] = {
14737 CreateMockWrite(req3, 0),
14738 };
14739
Ryan Hamilton0239aac2018-05-19 00:03:1314740 spdy::SpdySerializedFrame resp3(
14741 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
14742 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
bnc8016c1f2017-03-31 02:11:2914743 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14744 MockRead(ASYNC, 0, 3)};
14745
14746 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114747 SequencedSocketData data2(connect2, reads2, writes2);
bnc8016c1f2017-03-31 02:11:2914748 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14749
14750 AddSSLSocketData();
14751
14752 // Preload mail.example.org into HostCache.
14753 HostPortPair host_port("mail.example.org", 443);
14754 HostResolver::RequestInfo resolve_info(host_port);
14755 AddressList ignored;
14756 std::unique_ptr<HostResolver::Request> request;
14757 TestCompletionCallback callback;
14758 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14759 &ignored, callback.callback(),
14760 &request, NetLogWithSource());
14761 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14762 rv = callback.WaitForResult();
14763 EXPECT_THAT(rv, IsOk());
14764
14765 HttpRequestInfo request1;
14766 request1.method = "GET";
14767 request1.url = GURL("https://www.example.org/");
14768 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014769 request1.traffic_annotation =
14770 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914771 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14772
14773 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14774 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14775 rv = callback.WaitForResult();
14776 EXPECT_THAT(rv, IsOk());
14777
14778 const HttpResponseInfo* response = trans1.GetResponseInfo();
14779 ASSERT_TRUE(response);
14780 ASSERT_TRUE(response->headers);
14781 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14782 EXPECT_TRUE(response->was_fetched_via_spdy);
14783 EXPECT_TRUE(response->was_alpn_negotiated);
14784 std::string response_data;
14785 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14786 EXPECT_EQ("hello!", response_data);
14787
14788 HttpRequestInfo request2;
14789 request2.method = "GET";
14790 request2.url = GURL("https://mail.example.org/");
14791 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014792 request2.traffic_annotation =
14793 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2914794 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14795
14796 BoundTestNetLog log;
14797 rv = trans2.Start(&request2, callback.callback(), log.bound());
14798 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14799 rv = callback.WaitForResult();
14800 EXPECT_THAT(rv, IsOk());
14801
14802 response = trans2.GetResponseInfo();
14803 ASSERT_TRUE(response);
14804 ASSERT_TRUE(response->headers);
14805 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14806 EXPECT_TRUE(response->was_fetched_via_spdy);
14807 EXPECT_TRUE(response->was_alpn_negotiated);
14808 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14809 EXPECT_EQ("hello!", response_data);
14810
14811 TestNetLogEntry::List entries;
14812 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5914813 ExpectLogContainsSomewhere(
14814 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2914815 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5914816}
14817
14818// Test that HTTP 421 responses are properly returned to the caller if received
14819// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
14820// portions of the response.
14821TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
14822 // Two hosts resolve to the same IP address.
14823 const std::string ip_addr = "1.2.3.4";
14824 IPAddress ip;
14825 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
14826 IPEndPoint peer_addr = IPEndPoint(ip, 443);
14827
Jeremy Roman0579ed62017-08-29 15:56:1914828 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5914829 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
14830 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
14831
14832 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
14833
14834 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1314835 spdy::SpdySerializedFrame req1(
davidbence688ae2017-05-04 15:12:5914836 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
14837 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1314838 spdy::SpdySerializedFrame req2(
davidbence688ae2017-05-04 15:12:5914839 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1314840 spdy::SpdySerializedFrame rst(
14841 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
davidbence688ae2017-05-04 15:12:5914842 MockWrite writes1[] = {
14843 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
14844 CreateMockWrite(rst, 6),
14845 };
14846
14847 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1314848 spdy::SpdySerializedFrame resp1(
14849 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
14850 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
14851 spdy::SpdyHeaderBlock response_headers;
14852 response_headers[spdy::kHttp2StatusHeader] = "421";
14853 spdy::SpdySerializedFrame resp2(
davidbence688ae2017-05-04 15:12:5914854 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
14855 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
14856 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
14857
14858 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114859 SequencedSocketData data1(connect1, reads1, writes1);
davidbence688ae2017-05-04 15:12:5914860 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14861
14862 AddSSLSocketData();
14863
14864 // Retry the second request on a second connection. It returns 421 Misdirected
14865 // Retry again.
14866 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1314867 spdy::SpdySerializedFrame req3(
davidbence688ae2017-05-04 15:12:5914868 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
14869 MockWrite writes2[] = {
14870 CreateMockWrite(req3, 0),
14871 };
14872
Ryan Hamilton0239aac2018-05-19 00:03:1314873 spdy::SpdySerializedFrame resp3(
davidbence688ae2017-05-04 15:12:5914874 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
Ryan Hamilton0239aac2018-05-19 00:03:1314875 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
davidbence688ae2017-05-04 15:12:5914876 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
14877 MockRead(ASYNC, 0, 3)};
14878
14879 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0114880 SequencedSocketData data2(connect2, reads2, writes2);
davidbence688ae2017-05-04 15:12:5914881 session_deps_.socket_factory->AddSocketDataProvider(&data2);
14882
14883 AddSSLSocketData();
14884
14885 // Preload mail.example.org into HostCache.
14886 HostPortPair host_port("mail.example.org", 443);
14887 HostResolver::RequestInfo resolve_info(host_port);
14888 AddressList ignored;
14889 std::unique_ptr<HostResolver::Request> request;
14890 TestCompletionCallback callback;
14891 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
14892 &ignored, callback.callback(),
14893 &request, NetLogWithSource());
14894 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14895 rv = callback.WaitForResult();
14896 EXPECT_THAT(rv, IsOk());
14897
14898 HttpRequestInfo request1;
14899 request1.method = "GET";
14900 request1.url = GURL("https://www.example.org/");
14901 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014902 request1.traffic_annotation =
14903 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5914904 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
14905
14906 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
14907 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14908 rv = callback.WaitForResult();
14909 EXPECT_THAT(rv, IsOk());
14910
14911 const HttpResponseInfo* response = trans1.GetResponseInfo();
14912 ASSERT_TRUE(response);
14913 ASSERT_TRUE(response->headers);
14914 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
14915 EXPECT_TRUE(response->was_fetched_via_spdy);
14916 EXPECT_TRUE(response->was_alpn_negotiated);
14917 std::string response_data;
14918 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
14919 EXPECT_EQ("hello!", response_data);
14920
14921 HttpRequestInfo request2;
14922 request2.method = "GET";
14923 request2.url = GURL("https://mail.example.org/");
14924 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1014925 request2.traffic_annotation =
14926 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5914927 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
14928
14929 BoundTestNetLog log;
14930 rv = trans2.Start(&request2, callback.callback(), log.bound());
14931 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14932 rv = callback.WaitForResult();
14933 EXPECT_THAT(rv, IsOk());
14934
14935 // After a retry, the 421 Misdirected Request is reported back up to the
14936 // caller.
14937 response = trans2.GetResponseInfo();
14938 ASSERT_TRUE(response);
14939 ASSERT_TRUE(response->headers);
14940 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
14941 EXPECT_TRUE(response->was_fetched_via_spdy);
14942 EXPECT_TRUE(response->was_alpn_negotiated);
14943 EXPECT_TRUE(response->ssl_info.cert);
14944 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
14945 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2914946}
14947
bnc6dcd8192017-05-25 20:11:5014948class OneTimeCachingHostResolver : public MockHostResolverBase {
[email protected]e3ceb682011-06-28 23:55:4614949 public:
14950 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
bnc6dcd8192017-05-25 20:11:5014951 : MockHostResolverBase(/* use_caching = */ true), host_port_(host_port) {}
Chris Watkins7a41d3552017-12-01 02:13:2714952 ~OneTimeCachingHostResolver() override = default;
[email protected]e3ceb682011-06-28 23:55:4614953
dchengb03027d2014-10-21 12:00:2014954 int ResolveFromCache(const RequestInfo& info,
14955 AddressList* addresses,
tfarina42834112016-09-22 13:38:2014956 const NetLogWithSource& net_log) override {
bnc6dcd8192017-05-25 20:11:5014957 int rv = MockHostResolverBase::ResolveFromCache(info, addresses, net_log);
[email protected]95a214c2011-08-04 21:50:4014958 if (rv == OK && info.host_port_pair().Equals(host_port_))
bnc6dcd8192017-05-25 20:11:5014959 GetHostCache()->clear();
[email protected]e3ceb682011-06-28 23:55:4614960 return rv;
14961 }
14962
[email protected]e3ceb682011-06-28 23:55:4614963 private:
[email protected]e3ceb682011-06-28 23:55:4614964 const HostPortPair host_port_;
14965};
14966
bncd16676a2016-07-20 16:23:0114967TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1314968 UseIPConnectionPoolingWithHostCacheExpiration) {
[email protected]e3ceb682011-06-28 23:55:4614969 // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1914970 session_deps_.host_resolver = std::make_unique<OneTimeCachingHostResolver>(
bnca4d611d2016-09-22 19:55:3714971 HostPortPair("mail.example.com", 443));
danakj1fd259a02016-04-16 03:17:0914972 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4614973
bnc032658ba2016-09-26 18:17:1514974 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4614975
Ryan Hamilton0239aac2018-05-19 00:03:1314976 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4914977 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3814978 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1314979 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3714980 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4614981 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4114982 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4614983 };
Ryan Hamilton0239aac2018-05-19 00:03:1314984 spdy::SpdySerializedFrame host1_resp(
14985 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
14986 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4114987 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1314988 spdy::SpdySerializedFrame host2_resp(
14989 spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
14990 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4114991 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4614992 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114993 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
14994 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1314995 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4614996 };
14997
eroman36d84e54432016-03-17 03:23:0214998 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0214999 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115000 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715001 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615002
[email protected]aa22b242011-11-16 18:58:2915003 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615004 HttpRequestInfo request1;
15005 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315006 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615007 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015008 request1.traffic_annotation =
15009 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015010 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615011
tfarina42834112016-09-22 13:38:2015012 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115013 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15014 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615015
15016 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215017 ASSERT_TRUE(response);
15018 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215019 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615020
15021 std::string response_data;
robpercival214763f2016-07-01 23:27:0115022 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615023 EXPECT_EQ("hello!", response_data);
15024
15025 // Preload cache entries into HostCache.
bnca4d611d2016-09-22 19:55:3715026 HostResolver::RequestInfo resolve_info(HostPortPair("mail.example.com", 443));
[email protected]e3ceb682011-06-28 23:55:4615027 AddressList ignored;
maksim.sisov31452af2016-07-27 06:38:1015028 std::unique_ptr<HostResolver::Request> request;
bnc6dcd8192017-05-25 20:11:5015029 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
15030 &ignored, callback.callback(),
15031 &request, NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115032 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6e78dfb2011-07-28 21:34:4715033 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115034 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615035
15036 HttpRequestInfo request2;
15037 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715038 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615039 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015040 request2.traffic_annotation =
15041 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015042 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615043
tfarina42834112016-09-22 13:38:2015044 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115045 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15046 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615047
15048 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215049 ASSERT_TRUE(response);
15050 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215051 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615052 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215053 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115054 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615055 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615056}
15057
bncd16676a2016-07-20 16:23:0115058TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2315059 const std::string https_url = "https://www.example.org:8080/";
15060 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415061
15062 // SPDY GET for HTTPS URL
Ryan Hamilton0239aac2018-05-19 00:03:1315063 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915064 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415065
15066 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115067 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0415068 };
15069
Ryan Hamilton0239aac2018-05-19 00:03:1315070 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15071 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4115072 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5915073 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0415074
Ryan Sleevib8d7ea02018-05-07 20:01:0115075 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0415076 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715077 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415078
15079 // HTTP GET for the HTTP URL
15080 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1315081 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3415082 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315083 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3415084 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0415085 };
15086
15087 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1315088 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
15089 MockRead(ASYNC, 2, "hello"),
15090 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0415091 };
15092
Ryan Sleevib8d7ea02018-05-07 20:01:0115093 SequencedSocketData data2(reads2, writes2);
[email protected]8450d722012-07-02 19:14:0415094
[email protected]8450d722012-07-02 19:14:0415095 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615096 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715097 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15098 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15099 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0415100
danakj1fd259a02016-04-16 03:17:0915101 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0415102
15103 // Start the first transaction to set up the SpdySession
15104 HttpRequestInfo request1;
15105 request1.method = "GET";
15106 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415107 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015108 request1.traffic_annotation =
15109 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015110 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415111 TestCompletionCallback callback1;
15112 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015113 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515114 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415115
robpercival214763f2016-07-01 23:27:0115116 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415117 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15118
15119 // Now, start the HTTP request
15120 HttpRequestInfo request2;
15121 request2.method = "GET";
15122 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415123 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015124 request2.traffic_annotation =
15125 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015126 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415127 TestCompletionCallback callback2;
15128 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015129 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515130 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415131
robpercival214763f2016-07-01 23:27:0115132 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415133 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15134}
15135
bnc5452e2a2015-05-08 16:27:4215136// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
15137// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0115138TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2515139 url::SchemeHostPort server("https", "www.example.org", 443);
15140 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4215141
bnc8bef8da22016-05-30 01:28:2515142 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4215143 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615144 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215145 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15146
15147 // No data should be read from the alternative, because HTTP/1.1 is
15148 // negotiated.
15149 StaticSocketDataProvider data;
15150 session_deps_.socket_factory->AddSocketDataProvider(&data);
15151
15152 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4615153 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4215154 // mocked. This way the request relies on the alternate Job.
15155 StaticSocketDataProvider data_refused;
15156 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15157 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15158
zhongyi3d4a55e72016-04-22 20:36:4615159 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915160 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015161 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215162 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115163 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215164 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115165 http_server_properties->SetHttp2AlternativeService(
15166 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215167
bnc5452e2a2015-05-08 16:27:4215168 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4615169 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215170 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2515171 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e2018-02-07 07:41:1015172 request.traffic_annotation =
15173 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215174 TestCompletionCallback callback;
15175
15176 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5215177 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2015178 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5215179 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4215180}
15181
bnc40448a532015-05-11 19:13:1415182// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4615183// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1415184// succeeds, the request should succeed, even if the latter fails because
15185// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0115186TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2515187 url::SchemeHostPort server("https", "www.example.org", 443);
15188 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1415189
15190 // Negotiate HTTP/1.1 with alternative.
15191 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615192 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415193 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
15194
15195 // No data should be read from the alternative, because HTTP/1.1 is
15196 // negotiated.
15197 StaticSocketDataProvider data;
15198 session_deps_.socket_factory->AddSocketDataProvider(&data);
15199
zhongyi3d4a55e72016-04-22 20:36:4615200 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1415201 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615202 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1415203 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
15204
15205 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2515206 MockWrite("GET / HTTP/1.1\r\n"
15207 "Host: www.example.org\r\n"
15208 "Connection: keep-alive\r\n\r\n"),
15209 MockWrite("GET /second HTTP/1.1\r\n"
15210 "Host: www.example.org\r\n"
15211 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1415212 };
15213
15214 MockRead http_reads[] = {
15215 MockRead("HTTP/1.1 200 OK\r\n"),
15216 MockRead("Content-Type: text/html\r\n"),
15217 MockRead("Content-Length: 6\r\n\r\n"),
15218 MockRead("foobar"),
15219 MockRead("HTTP/1.1 200 OK\r\n"),
15220 MockRead("Content-Type: text/html\r\n"),
15221 MockRead("Content-Length: 7\r\n\r\n"),
15222 MockRead("another"),
15223 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115224 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc40448a532015-05-11 19:13:1415225 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15226
zhongyi3d4a55e72016-04-22 20:36:4615227 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915228 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015229 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1415230 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115231 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215232 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115233 http_server_properties->SetHttp2AlternativeService(
15234 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1415235
15236 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15237 HttpRequestInfo request1;
15238 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2515239 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1415240 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015241 request1.traffic_annotation =
15242 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415243 TestCompletionCallback callback1;
15244
tfarina42834112016-09-22 13:38:2015245 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415246 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115247 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415248
15249 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215250 ASSERT_TRUE(response1);
15251 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1415252 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
15253
15254 std::string response_data1;
robpercival214763f2016-07-01 23:27:0115255 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1415256 EXPECT_EQ("foobar", response_data1);
15257
15258 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
15259 // for alternative service.
15260 EXPECT_TRUE(
15261 http_server_properties->IsAlternativeServiceBroken(alternative_service));
15262
zhongyi3d4a55e72016-04-22 20:36:4615263 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1415264 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4615265 // to server.
bnc40448a532015-05-11 19:13:1415266 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15267 HttpRequestInfo request2;
15268 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2515269 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1415270 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015271 request2.traffic_annotation =
15272 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1415273 TestCompletionCallback callback2;
15274
tfarina42834112016-09-22 13:38:2015275 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1415276 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0115277 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1415278
15279 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215280 ASSERT_TRUE(response2);
15281 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1415282 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
15283
15284 std::string response_data2;
robpercival214763f2016-07-01 23:27:0115285 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1415286 EXPECT_EQ("another", response_data2);
15287}
15288
bnc5452e2a2015-05-08 16:27:4215289// Alternative service requires HTTP/2 (or SPDY), but there is already a
15290// HTTP/1.1 socket open to the alternative server. That socket should not be
15291// used.
bncd16676a2016-07-20 16:23:0115292TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4615293 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4215294 HostPortPair alternative("alternative.example.org", 443);
15295 std::string origin_url = "https://origin.example.org:443";
15296 std::string alternative_url = "https://alternative.example.org:443";
15297
15298 // Negotiate HTTP/1.1 with alternative.example.org.
15299 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615300 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4215301 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15302
15303 // HTTP/1.1 data for |request1| and |request2|.
15304 MockWrite http_writes[] = {
15305 MockWrite(
15306 "GET / HTTP/1.1\r\n"
15307 "Host: alternative.example.org\r\n"
15308 "Connection: keep-alive\r\n\r\n"),
15309 MockWrite(
15310 "GET / HTTP/1.1\r\n"
15311 "Host: alternative.example.org\r\n"
15312 "Connection: keep-alive\r\n\r\n"),
15313 };
15314
15315 MockRead http_reads[] = {
15316 MockRead(
15317 "HTTP/1.1 200 OK\r\n"
15318 "Content-Type: text/html; charset=iso-8859-1\r\n"
15319 "Content-Length: 40\r\n\r\n"
15320 "first HTTP/1.1 response from alternative"),
15321 MockRead(
15322 "HTTP/1.1 200 OK\r\n"
15323 "Content-Type: text/html; charset=iso-8859-1\r\n"
15324 "Content-Length: 41\r\n\r\n"
15325 "second HTTP/1.1 response from alternative"),
15326 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115327 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc5452e2a2015-05-08 16:27:4215328 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15329
15330 // This test documents that an alternate Job should not pool to an already
15331 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4615332 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4215333 StaticSocketDataProvider data_refused;
15334 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
15335 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
15336
zhongyi3d4a55e72016-04-22 20:36:4615337 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0915338 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4015339 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4215340 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2115341 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1215342 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2115343 http_server_properties->SetHttp2AlternativeService(
15344 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4215345
15346 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4215347 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4615348 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215349 request1.method = "GET";
15350 request1.url = GURL(alternative_url);
15351 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015352 request1.traffic_annotation =
15353 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215354 TestCompletionCallback callback1;
15355
tfarina42834112016-09-22 13:38:2015356 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115357 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615358 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215359 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5215360 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4215361 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215362 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215363 EXPECT_FALSE(response1->was_fetched_via_spdy);
15364 std::string response_data1;
bnc691fda62016-08-12 00:43:1615365 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4215366 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
15367
15368 // Request for origin.example.org, which has an alternative service. This
15369 // will start two Jobs: the alternative looks for connections to pool to,
15370 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4615371 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4215372 // this request fails.
bnc5452e2a2015-05-08 16:27:4215373 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4615374 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215375 request2.method = "GET";
15376 request2.url = GURL(origin_url);
15377 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015378 request2.traffic_annotation =
15379 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215380 TestCompletionCallback callback2;
15381
tfarina42834112016-09-22 13:38:2015382 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115383 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4215384
15385 // Another transaction to alternative. This is to test that the HTTP/1.1
15386 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4215387 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4615388 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4215389 request3.method = "GET";
15390 request3.url = GURL(alternative_url);
15391 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015392 request3.traffic_annotation =
15393 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4215394 TestCompletionCallback callback3;
15395
tfarina42834112016-09-22 13:38:2015396 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115397 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1615398 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4215399 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5215400 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4215401 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5215402 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4215403 EXPECT_FALSE(response3->was_fetched_via_spdy);
15404 std::string response_data3;
bnc691fda62016-08-12 00:43:1615405 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4215406 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
15407}
15408
bncd16676a2016-07-20 16:23:0115409TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2315410 const std::string https_url = "https://www.example.org:8080/";
15411 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415412
rdsmithebb50aa2015-11-12 03:44:3815413 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0115414 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3815415
[email protected]8450d722012-07-02 19:14:0415416 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2315417 const HostPortPair host_port_pair("www.example.org", 8080);
Ryan Hamilton0239aac2018-05-19 00:03:1315418 spdy::SpdySerializedFrame connect(
lgarrona91df87f2014-12-05 00:51:3415419 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
Ryan Hamilton0239aac2018-05-19 00:03:1315420 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915421 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315422 spdy::SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0215423 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3915424
15425 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
Ryan Hamilton0239aac2018-05-19 00:03:1315426 spdy::SpdyHeaderBlock req2_block;
15427 req2_block[spdy::kHttp2MethodHeader] = "GET";
15428 req2_block[spdy::kHttp2AuthorityHeader] = "www.example.org:8080";
15429 req2_block[spdy::kHttp2SchemeHeader] = "http";
15430 req2_block[spdy::kHttp2PathHeader] = "/";
15431 spdy::SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1515432 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0415433
15434 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115435 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
15436 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0415437 };
15438
Ryan Hamilton0239aac2018-05-19 00:03:1315439 spdy::SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1515440 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315441 spdy::SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1515442 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315443 spdy::SpdySerializedFrame body1(
15444 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
15445 spdy::SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3815446 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315447 spdy::SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3815448 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315449 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 3));
15450 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3315451 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115452 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3315453 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4115454 CreateMockRead(wrapped_resp1, 4),
15455 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3315456 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4115457 CreateMockRead(resp2, 8),
15458 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3315459 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
15460 };
[email protected]8450d722012-07-02 19:14:0415461
Ryan Sleevib8d7ea02018-05-07 20:01:0115462 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0415463 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715464 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415465
Lily Houghton8c2f97d2018-01-22 05:06:5915466 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4915467 ProxyResolutionService::CreateFixedFromPacResult(
15468 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115469 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715470 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0415471 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615472 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315473 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0415474 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615475 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315476 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15477 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0415478
danakj1fd259a02016-04-16 03:17:0915479 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0415480
15481 // Start the first transaction to set up the SpdySession
15482 HttpRequestInfo request1;
15483 request1.method = "GET";
15484 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415485 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015486 request1.traffic_annotation =
15487 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015488 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415489 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2015490 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415491
mmenke666a6fea2015-12-19 04:16:3315492 // This pause is a hack to avoid running into https://crbug.com/497228.
15493 data1.RunUntilPaused();
15494 base::RunLoop().RunUntilIdle();
15495 data1.Resume();
robpercival214763f2016-07-01 23:27:0115496 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0415497 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15498
[email protected]f6c63db52013-02-02 00:35:2215499 LoadTimingInfo load_timing_info1;
15500 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
15501 TestLoadTimingNotReusedWithPac(load_timing_info1,
15502 CONNECT_TIMING_HAS_SSL_TIMES);
15503
mmenke666a6fea2015-12-19 04:16:3315504 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0415505 HttpRequestInfo request2;
15506 request2.method = "GET";
15507 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415508 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015509 request2.traffic_annotation =
15510 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015511 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415512 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2015513 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0415514
mmenke666a6fea2015-12-19 04:16:3315515 // This pause is a hack to avoid running into https://crbug.com/497228.
15516 data1.RunUntilPaused();
15517 base::RunLoop().RunUntilIdle();
15518 data1.Resume();
robpercival214763f2016-07-01 23:27:0115519 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3315520
[email protected]8450d722012-07-02 19:14:0415521 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2215522
15523 LoadTimingInfo load_timing_info2;
15524 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
15525 // The established SPDY sessions is considered reused by the HTTP request.
15526 TestLoadTimingReusedWithPac(load_timing_info2);
15527 // HTTP requests over a SPDY session should have a different connection
15528 // socket_log_id than requests over a tunnel.
15529 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0415530}
15531
[email protected]2d88e7d2012-07-19 17:55:1715532// Test that in the case where we have a SPDY session to a SPDY proxy
15533// that we do not pool other origins that resolve to the same IP when
15534// the certificate does not match the new origin.
15535// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0115536TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2315537 const std::string url1 = "http://www.example.org/";
15538 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1715539 const std::string ip_addr = "1.2.3.4";
15540
rdsmithebb50aa2015-11-12 03:44:3815541 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0115542 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3815543
[email protected]2d88e7d2012-07-19 17:55:1715544 // SPDY GET for HTTP URL (through SPDY proxy)
Ryan Hamilton0239aac2018-05-19 00:03:1315545 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2315546 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:1315547 spdy::SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1515548 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1715549
15550 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115551 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1715552 };
15553
Ryan Hamilton0239aac2018-05-19 00:03:1315554 spdy::SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15555 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1715556 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4115557 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
15558 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1715559 };
15560
Ryan Sleevib8d7ea02018-05-07 20:01:0115561 SequencedSocketData data1(reads1, writes1);
martijnfe9636e2016-02-06 14:33:3215562 IPAddress ip;
martijn654c8c42016-02-10 22:10:5915563 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1715564 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15565 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3315566 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1715567
15568 // SPDY GET for HTTPS URL (direct)
Ryan Hamilton0239aac2018-05-19 00:03:1315569 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915570 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1715571
15572 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115573 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1715574 };
15575
Ryan Hamilton0239aac2018-05-19 00:03:1315576 spdy::SpdySerializedFrame resp2(
15577 spdy_util_secure.ConstructSpdyGetReply(NULL, 0, 1));
15578 spdy::SpdySerializedFrame body2(
15579 spdy_util_secure.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4115580 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3315581 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1715582
Ryan Sleevib8d7ea02018-05-07 20:01:0115583 SequencedSocketData data2(reads2, writes2);
[email protected]2d88e7d2012-07-19 17:55:1715584 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3315585 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1715586
15587 // Set up a proxy config that sends HTTP requests to a proxy, and
15588 // all others direct.
15589 ProxyConfig proxy_config;
15590 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Ramin Halavatica8d5252018-03-12 05:33:4915591 session_deps_.proxy_resolution_service =
15592 std::make_unique<ProxyResolutionService>(
15593 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
15594 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
15595 nullptr, nullptr);
[email protected]2d88e7d2012-07-19 17:55:1715596
bncce36dca22015-04-21 22:11:2315597 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3615598 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1715599 // Load a valid cert. Note, that this does not need to
15600 // be valid for proxy because the MockSSLClientSocket does
15601 // not actually verify it. But SpdySession will use this
15602 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4915603 ssl1.ssl_info.cert =
15604 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
15605 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3315606 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15607 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1715608
15609 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3615610 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3315611 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15612 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1715613
Jeremy Roman0579ed62017-08-29 15:56:1915614 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2315615 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0715616 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1715617
danakj1fd259a02016-04-16 03:17:0915618 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1715619
15620 // Start the first transaction to set up the SpdySession
15621 HttpRequestInfo request1;
15622 request1.method = "GET";
15623 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1715624 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015625 request1.traffic_annotation =
15626 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015627 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715628 TestCompletionCallback callback1;
15629 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015630 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3315631 // This pause is a hack to avoid running into https://crbug.com/497228.
15632 data1.RunUntilPaused();
15633 base::RunLoop().RunUntilIdle();
15634 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1715635
robpercival214763f2016-07-01 23:27:0115636 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715637 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15638
15639 // Now, start the HTTP request
15640 HttpRequestInfo request2;
15641 request2.method = "GET";
15642 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1715643 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015644 request2.traffic_annotation =
15645 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015646 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1715647 TestCompletionCallback callback2;
15648 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015649 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515650 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1715651
15652 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0115653 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1715654 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15655}
15656
[email protected]85f97342013-04-17 06:12:2415657// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
15658// error) in SPDY session, removes the socket from pool and closes the SPDY
15659// session. Verify that new url's from the same HttpNetworkSession (and a new
15660// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0115661TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2315662 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2415663
15664 MockRead reads1[] = {
15665 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
15666 };
15667
Ryan Sleevib8d7ea02018-05-07 20:01:0115668 SequencedSocketData data1(reads1, base::span<MockWrite>());
[email protected]85f97342013-04-17 06:12:2415669
Ryan Hamilton0239aac2018-05-19 00:03:1315670 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4915671 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2415672 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4115673 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2415674 };
15675
Ryan Hamilton0239aac2018-05-19 00:03:1315676 spdy::SpdySerializedFrame resp2(spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15677 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2415678 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4115679 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
15680 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2415681 };
15682
Ryan Sleevib8d7ea02018-05-07 20:01:0115683 SequencedSocketData data2(reads2, writes2);
[email protected]85f97342013-04-17 06:12:2415684
[email protected]85f97342013-04-17 06:12:2415685 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615686 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015687 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15688 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2415689
15690 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615691 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5015692 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15693 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2415694
danakj1fd259a02016-04-16 03:17:0915695 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5015696 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2415697
15698 // Start the first transaction to set up the SpdySession and verify that
15699 // connection was closed.
15700 HttpRequestInfo request1;
15701 request1.method = "GET";
15702 request1.url = GURL(https_url);
15703 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015704 request1.traffic_annotation =
15705 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015706 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415707 TestCompletionCallback callback1;
15708 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015709 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0115710 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2415711
15712 // Now, start the second request and make sure it succeeds.
15713 HttpRequestInfo request2;
15714 request2.method = "GET";
15715 request2.url = GURL(https_url);
15716 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015717 request2.traffic_annotation =
15718 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015719 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2415720 TestCompletionCallback callback2;
15721 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015722 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2415723
robpercival214763f2016-07-01 23:27:0115724 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2415725 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15726}
15727
bncd16676a2016-07-20 16:23:0115728TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0315729 ClientSocketPoolManager::set_max_sockets_per_group(
15730 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15731 ClientSocketPoolManager::set_max_sockets_per_pool(
15732 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
15733
15734 // Use two different hosts with different IPs so they don't get pooled.
15735 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
15736 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0915737 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0315738
15739 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615740 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315741 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615742 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0315743 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
15744 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
15745
Ryan Hamilton0239aac2018-05-19 00:03:1315746 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915747 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315748 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115749 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0315750 };
Ryan Hamilton0239aac2018-05-19 00:03:1315751 spdy::SpdySerializedFrame host1_resp(
15752 spdy_util_.ConstructSpdyGetReply(NULL, 0, 1));
15753 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115754 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315755 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115756 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915757 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315758 };
15759
rdsmithebb50aa2015-11-12 03:44:3815760 // Use a separate test instance for the separate SpdySession that will be
15761 // created.
bncd16676a2016-07-20 16:23:0115762 SpdyTestUtil spdy_util_2;
Ryan Sleevib8d7ea02018-05-07 20:01:0115763 SequencedSocketData spdy1_data(spdy1_reads, spdy1_writes);
Bence Béky53a5aef2018-03-29 21:54:1215764 session_deps_.socket_factory->AddSocketDataProvider(&spdy1_data);
[email protected]483fa202013-05-14 01:07:0315765
Ryan Hamilton0239aac2018-05-19 00:03:1315766 spdy::SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4915767 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0315768 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115769 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0315770 };
Ryan Hamilton0239aac2018-05-19 00:03:1315771 spdy::SpdySerializedFrame host2_resp(
15772 spdy_util_2.ConstructSpdyGetReply(NULL, 0, 1));
15773 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115774 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0315775 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115776 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5915777 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0315778 };
15779
Ryan Sleevib8d7ea02018-05-07 20:01:0115780 SequencedSocketData spdy2_data(spdy2_reads, spdy2_writes);
Bence Béky53a5aef2018-03-29 21:54:1215781 session_deps_.socket_factory->AddSocketDataProvider(&spdy2_data);
[email protected]483fa202013-05-14 01:07:0315782
15783 MockWrite http_write[] = {
15784 MockWrite("GET / HTTP/1.1\r\n"
15785 "Host: www.a.com\r\n"
15786 "Connection: keep-alive\r\n\r\n"),
15787 };
15788
15789 MockRead http_read[] = {
15790 MockRead("HTTP/1.1 200 OK\r\n"),
15791 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
15792 MockRead("Content-Length: 6\r\n\r\n"),
15793 MockRead("hello!"),
15794 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115795 StaticSocketDataProvider http_data(http_read, http_write);
[email protected]483fa202013-05-14 01:07:0315796 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
15797
15798 HostPortPair host_port_pair_a("www.a.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415799 SpdySessionKey spdy_session_key_a(host_port_pair_a, ProxyServer::Direct(),
15800 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315801 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615802 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315803
15804 TestCompletionCallback callback;
15805 HttpRequestInfo request1;
15806 request1.method = "GET";
15807 request1.url = GURL("https://www.a.com/");
15808 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015809 request1.traffic_annotation =
15810 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815811 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1915812 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315813
tfarina42834112016-09-22 13:38:2015814 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115815 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15816 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315817
15818 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215819 ASSERT_TRUE(response);
15820 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215821 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315822 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215823 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0315824
15825 std::string response_data;
robpercival214763f2016-07-01 23:27:0115826 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315827 EXPECT_EQ("hello!", response_data);
15828 trans.reset();
15829 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615830 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315831
15832 HostPortPair host_port_pair_b("www.b.com", 443);
Paul Jensena457017a2018-01-19 23:52:0415833 SpdySessionKey spdy_session_key_b(host_port_pair_b, ProxyServer::Direct(),
15834 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315835 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615836 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315837 HttpRequestInfo request2;
15838 request2.method = "GET";
15839 request2.url = GURL("https://www.b.com/");
15840 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015841 request2.traffic_annotation =
15842 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815843 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915844 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315845
tfarina42834112016-09-22 13:38:2015846 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115847 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15848 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315849
15850 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215851 ASSERT_TRUE(response);
15852 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215853 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0315854 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215855 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115856 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315857 EXPECT_EQ("hello!", response_data);
15858 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615859 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315860 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2615861 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315862
15863 HostPortPair host_port_pair_a1("www.a.com", 80);
Paul Jensena457017a2018-01-19 23:52:0415864 SpdySessionKey spdy_session_key_a1(host_port_pair_a1, ProxyServer::Direct(),
15865 PRIVACY_MODE_DISABLED, SocketTag());
[email protected]483fa202013-05-14 01:07:0315866 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615867 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0315868 HttpRequestInfo request3;
15869 request3.method = "GET";
15870 request3.url = GURL("http://www.a.com/");
15871 request3.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1015872 request3.traffic_annotation =
15873 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5815874 trans =
Jeremy Roman0579ed62017-08-29 15:56:1915875 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0315876
tfarina42834112016-09-22 13:38:2015877 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115878 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15879 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0315880
15881 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5215882 ASSERT_TRUE(response);
15883 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0315884 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
15885 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215886 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115887 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0315888 EXPECT_EQ("hello!", response_data);
15889 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615890 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0315891 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2615892 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0315893}
15894
bncd16676a2016-07-20 16:23:0115895TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415896 HttpRequestInfo request;
15897 request.method = "GET";
bncce36dca22015-04-21 22:11:2315898 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1015899 request.traffic_annotation =
15900 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415901
danakj1fd259a02016-04-16 03:17:0915902 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615903 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415904
ttuttled9dbc652015-09-29 20:00:5915905 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415906 StaticSocketDataProvider data;
15907 data.set_connect_data(mock_connect);
15908 session_deps_.socket_factory->AddSocketDataProvider(&data);
15909
15910 TestCompletionCallback callback;
15911
tfarina42834112016-09-22 13:38:2015912 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115913 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415914
15915 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115916 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415917
[email protected]79e1fd62013-06-20 06:50:0415918 // We don't care whether this succeeds or fails, but it shouldn't crash.
15919 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615920 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715921
15922 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615923 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715924 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115925 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915926
15927 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615928 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915929 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415930}
15931
bncd16676a2016-07-20 16:23:0115932TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0415933 HttpRequestInfo request;
15934 request.method = "GET";
bncce36dca22015-04-21 22:11:2315935 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1015936 request.traffic_annotation =
15937 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415938
danakj1fd259a02016-04-16 03:17:0915939 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615940 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415941
ttuttled9dbc652015-09-29 20:00:5915942 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0415943 StaticSocketDataProvider data;
15944 data.set_connect_data(mock_connect);
15945 session_deps_.socket_factory->AddSocketDataProvider(&data);
15946
15947 TestCompletionCallback callback;
15948
tfarina42834112016-09-22 13:38:2015949 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115950 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415951
15952 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115953 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0415954
[email protected]79e1fd62013-06-20 06:50:0415955 // We don't care whether this succeeds or fails, but it shouldn't crash.
15956 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615957 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4715958
15959 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1615960 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4715961 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0115962 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5915963
15964 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1615965 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5915966 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0415967}
15968
bncd16676a2016-07-20 16:23:0115969TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0415970 HttpRequestInfo request;
15971 request.method = "GET";
bncce36dca22015-04-21 22:11:2315972 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1015973 request.traffic_annotation =
15974 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0415975
danakj1fd259a02016-04-16 03:17:0915976 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615977 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0415978
15979 MockWrite data_writes[] = {
15980 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
15981 };
15982 MockRead data_reads[] = {
15983 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
15984 };
15985
Ryan Sleevib8d7ea02018-05-07 20:01:0115986 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0415987 session_deps_.socket_factory->AddSocketDataProvider(&data);
15988
15989 TestCompletionCallback callback;
15990
tfarina42834112016-09-22 13:38:2015991 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115992 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0415993
15994 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115995 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0415996
[email protected]79e1fd62013-06-20 06:50:0415997 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1615998 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0415999 EXPECT_TRUE(request_headers.HasHeader("Host"));
16000}
16001
bncd16676a2016-07-20 16:23:0116002TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416003 HttpRequestInfo request;
16004 request.method = "GET";
bncce36dca22015-04-21 22:11:2316005 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016006 request.traffic_annotation =
16007 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416008
danakj1fd259a02016-04-16 03:17:0916009 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616010 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416011
16012 MockWrite data_writes[] = {
16013 MockWrite(ASYNC, ERR_CONNECTION_RESET),
16014 };
16015 MockRead data_reads[] = {
16016 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16017 };
16018
Ryan Sleevib8d7ea02018-05-07 20:01:0116019 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416020 session_deps_.socket_factory->AddSocketDataProvider(&data);
16021
16022 TestCompletionCallback callback;
16023
tfarina42834112016-09-22 13:38:2016024 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116025 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416026
16027 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116028 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416029
[email protected]79e1fd62013-06-20 06:50:0416030 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616031 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416032 EXPECT_TRUE(request_headers.HasHeader("Host"));
16033}
16034
bncd16676a2016-07-20 16:23:0116035TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416036 HttpRequestInfo request;
16037 request.method = "GET";
bncce36dca22015-04-21 22:11:2316038 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016039 request.traffic_annotation =
16040 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416041
danakj1fd259a02016-04-16 03:17:0916042 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616043 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416044
16045 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316046 MockWrite(
16047 "GET / HTTP/1.1\r\n"
16048 "Host: www.example.org\r\n"
16049 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416050 };
16051 MockRead data_reads[] = {
16052 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
16053 };
16054
Ryan Sleevib8d7ea02018-05-07 20:01:0116055 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416056 session_deps_.socket_factory->AddSocketDataProvider(&data);
16057
16058 TestCompletionCallback callback;
16059
tfarina42834112016-09-22 13:38:2016060 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116061 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416062
16063 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116064 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416065
[email protected]79e1fd62013-06-20 06:50:0416066 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616067 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416068 EXPECT_TRUE(request_headers.HasHeader("Host"));
16069}
16070
bncd16676a2016-07-20 16:23:0116071TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416072 HttpRequestInfo request;
16073 request.method = "GET";
bncce36dca22015-04-21 22:11:2316074 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016075 request.traffic_annotation =
16076 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416077
danakj1fd259a02016-04-16 03:17:0916078 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616079 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416080
16081 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316082 MockWrite(
16083 "GET / HTTP/1.1\r\n"
16084 "Host: www.example.org\r\n"
16085 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416086 };
16087 MockRead data_reads[] = {
16088 MockRead(ASYNC, ERR_CONNECTION_RESET),
16089 };
16090
Ryan Sleevib8d7ea02018-05-07 20:01:0116091 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416092 session_deps_.socket_factory->AddSocketDataProvider(&data);
16093
16094 TestCompletionCallback callback;
16095
tfarina42834112016-09-22 13:38:2016096 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116097 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416098
16099 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116100 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416101
[email protected]79e1fd62013-06-20 06:50:0416102 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616103 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416104 EXPECT_TRUE(request_headers.HasHeader("Host"));
16105}
16106
bncd16676a2016-07-20 16:23:0116107TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0416108 HttpRequestInfo request;
16109 request.method = "GET";
bncce36dca22015-04-21 22:11:2316110 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0416111 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e2018-02-07 07:41:1016112 request.traffic_annotation =
16113 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416114
danakj1fd259a02016-04-16 03:17:0916115 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616116 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416117
16118 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316119 MockWrite(
16120 "GET / HTTP/1.1\r\n"
16121 "Host: www.example.org\r\n"
16122 "Connection: keep-alive\r\n"
16123 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416124 };
16125 MockRead data_reads[] = {
16126 MockRead("HTTP/1.1 200 OK\r\n"
16127 "Content-Length: 5\r\n\r\n"
16128 "hello"),
16129 MockRead(ASYNC, ERR_UNEXPECTED),
16130 };
16131
Ryan Sleevib8d7ea02018-05-07 20:01:0116132 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416133 session_deps_.socket_factory->AddSocketDataProvider(&data);
16134
16135 TestCompletionCallback callback;
16136
tfarina42834112016-09-22 13:38:2016137 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116138 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416139
16140 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116141 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0416142
16143 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616144 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416145 std::string foo;
16146 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
16147 EXPECT_EQ("bar", foo);
16148}
16149
[email protected]043b68c82013-08-22 23:41:5216150// Tests that when a used socket is returned to the SSL socket pool, it's closed
16151// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116152TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5216153 ClientSocketPoolManager::set_max_sockets_per_group(
16154 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16155 ClientSocketPoolManager::set_max_sockets_per_pool(
16156 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16157
16158 // Set up SSL request.
16159
16160 HttpRequestInfo ssl_request;
16161 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2316162 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016163 ssl_request.traffic_annotation =
16164 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216165
16166 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2316167 MockWrite(
16168 "GET / HTTP/1.1\r\n"
16169 "Host: www.example.org\r\n"
16170 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216171 };
16172 MockRead ssl_reads[] = {
16173 MockRead("HTTP/1.1 200 OK\r\n"),
16174 MockRead("Content-Length: 11\r\n\r\n"),
16175 MockRead("hello world"),
16176 MockRead(SYNCHRONOUS, OK),
16177 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116178 StaticSocketDataProvider ssl_data(ssl_reads, ssl_writes);
[email protected]043b68c82013-08-22 23:41:5216179 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16180
16181 SSLSocketDataProvider ssl(ASYNC, OK);
16182 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16183
16184 // Set up HTTP request.
16185
16186 HttpRequestInfo http_request;
16187 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316188 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016189 http_request.traffic_annotation =
16190 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216191
16192 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316193 MockWrite(
16194 "GET / HTTP/1.1\r\n"
16195 "Host: www.example.org\r\n"
16196 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216197 };
16198 MockRead http_reads[] = {
16199 MockRead("HTTP/1.1 200 OK\r\n"),
16200 MockRead("Content-Length: 7\r\n\r\n"),
16201 MockRead("falafel"),
16202 MockRead(SYNCHRONOUS, OK),
16203 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116204 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5216205 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16206
danakj1fd259a02016-04-16 03:17:0916207 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216208
16209 // Start the SSL request.
16210 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1616211 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016212 ASSERT_EQ(ERR_IO_PENDING,
16213 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
16214 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5216215
16216 // Start the HTTP request. Pool should stall.
16217 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616218 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016219 ASSERT_EQ(ERR_IO_PENDING,
16220 http_trans.Start(&http_request, http_callback.callback(),
16221 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116222 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216223
16224 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0116225 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216226 std::string response_data;
bnc691fda62016-08-12 00:43:1616227 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216228 EXPECT_EQ("hello world", response_data);
16229
16230 // The SSL socket should automatically be closed, so the HTTP request can
16231 // start.
dcheng48459ac22014-08-26 00:46:4116232 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
16233 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216234
16235 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0116236 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1616237 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216238 EXPECT_EQ("falafel", response_data);
16239
dcheng48459ac22014-08-26 00:46:4116240 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216241}
16242
16243// Tests that when a SSL connection is established but there's no corresponding
16244// request that needs it, the new socket is closed if the transport socket pool
16245// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0116246TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5216247 ClientSocketPoolManager::set_max_sockets_per_group(
16248 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16249 ClientSocketPoolManager::set_max_sockets_per_pool(
16250 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16251
16252 // Set up an ssl request.
16253
16254 HttpRequestInfo ssl_request;
16255 ssl_request.method = "GET";
16256 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e2018-02-07 07:41:1016257 ssl_request.traffic_annotation =
16258 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216259
16260 // No data will be sent on the SSL socket.
16261 StaticSocketDataProvider ssl_data;
16262 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
16263
16264 SSLSocketDataProvider ssl(ASYNC, OK);
16265 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16266
16267 // Set up HTTP request.
16268
16269 HttpRequestInfo http_request;
16270 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2316271 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016272 http_request.traffic_annotation =
16273 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5216274
16275 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2316276 MockWrite(
16277 "GET / HTTP/1.1\r\n"
16278 "Host: www.example.org\r\n"
16279 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5216280 };
16281 MockRead http_reads[] = {
16282 MockRead("HTTP/1.1 200 OK\r\n"),
16283 MockRead("Content-Length: 7\r\n\r\n"),
16284 MockRead("falafel"),
16285 MockRead(SYNCHRONOUS, OK),
16286 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116287 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5216288 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16289
danakj1fd259a02016-04-16 03:17:0916290 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5216291
16292 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
16293 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2916294 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5916295 http_stream_factory->PreconnectStreams(1, ssl_request);
dcheng48459ac22014-08-26 00:46:4116296 EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216297
16298 // Start the HTTP request. Pool should stall.
16299 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1616300 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016301 ASSERT_EQ(ERR_IO_PENDING,
16302 http_trans.Start(&http_request, http_callback.callback(),
16303 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4116304 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5216305
16306 // The SSL connection will automatically be closed once the connection is
16307 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0116308 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5216309 std::string response_data;
bnc691fda62016-08-12 00:43:1616310 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5216311 EXPECT_EQ("falafel", response_data);
16312
dcheng48459ac22014-08-26 00:46:4116313 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5216314}
16315
bncd16676a2016-07-20 16:23:0116316TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916317 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216318 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916319 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216320 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416321
16322 HttpRequestInfo request;
16323 request.method = "POST";
16324 request.url = GURL("http://www.foo.com/");
16325 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016326 request.traffic_annotation =
16327 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416328
danakj1fd259a02016-04-16 03:17:0916329 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616330 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416331 // Send headers successfully, but get an error while sending the body.
16332 MockWrite data_writes[] = {
16333 MockWrite("POST / HTTP/1.1\r\n"
16334 "Host: www.foo.com\r\n"
16335 "Connection: keep-alive\r\n"
16336 "Content-Length: 3\r\n\r\n"),
16337 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16338 };
16339
16340 MockRead data_reads[] = {
16341 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16342 MockRead("hello world"),
16343 MockRead(SYNCHRONOUS, OK),
16344 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116345 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416346 session_deps_.socket_factory->AddSocketDataProvider(&data);
16347
16348 TestCompletionCallback callback;
16349
tfarina42834112016-09-22 13:38:2016350 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116351 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416352
16353 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116354 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416355
bnc691fda62016-08-12 00:43:1616356 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216357 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416358
wezca1070932016-05-26 20:30:5216359 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416360 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16361
16362 std::string response_data;
bnc691fda62016-08-12 00:43:1616363 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116364 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416365 EXPECT_EQ("hello world", response_data);
16366}
16367
16368// This test makes sure the retry logic doesn't trigger when reading an error
16369// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0116370TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416371 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0916372 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5416373 MockWrite data_writes[] = {
16374 MockWrite("GET / HTTP/1.1\r\n"
16375 "Host: www.foo.com\r\n"
16376 "Connection: keep-alive\r\n\r\n"),
16377 MockWrite("POST / HTTP/1.1\r\n"
16378 "Host: www.foo.com\r\n"
16379 "Connection: keep-alive\r\n"
16380 "Content-Length: 3\r\n\r\n"),
16381 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16382 };
16383
16384 MockRead data_reads[] = {
16385 MockRead("HTTP/1.1 200 Peachy\r\n"
16386 "Content-Length: 14\r\n\r\n"),
16387 MockRead("first response"),
16388 MockRead("HTTP/1.1 400 Not OK\r\n"
16389 "Content-Length: 15\r\n\r\n"),
16390 MockRead("second response"),
16391 MockRead(SYNCHRONOUS, OK),
16392 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116393 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416394 session_deps_.socket_factory->AddSocketDataProvider(&data);
16395
16396 TestCompletionCallback callback;
16397 HttpRequestInfo request1;
16398 request1.method = "GET";
16399 request1.url = GURL("http://www.foo.com/");
16400 request1.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016401 request1.traffic_annotation =
16402 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416403
bnc87dcefc2017-05-25 12:47:5816404 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1916405 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016406 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116407 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416408
16409 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116410 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416411
16412 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5216413 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5416414
wezca1070932016-05-26 20:30:5216415 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5416416 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
16417
16418 std::string response_data1;
16419 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0116420 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416421 EXPECT_EQ("first response", response_data1);
16422 // Delete the transaction to release the socket back into the socket pool.
16423 trans1.reset();
16424
danakj1fd259a02016-04-16 03:17:0916425 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216426 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916427 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216428 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416429
16430 HttpRequestInfo request2;
16431 request2.method = "POST";
16432 request2.url = GURL("http://www.foo.com/");
16433 request2.upload_data_stream = &upload_data_stream;
16434 request2.load_flags = 0;
Ramin Halavatib5e433e2018-02-07 07:41:1016435 request2.traffic_annotation =
16436 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416437
bnc691fda62016-08-12 00:43:1616438 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2016439 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116440 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416441
16442 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116443 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416444
bnc691fda62016-08-12 00:43:1616445 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216446 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5416447
wezca1070932016-05-26 20:30:5216448 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5416449 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
16450
16451 std::string response_data2;
bnc691fda62016-08-12 00:43:1616452 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0116453 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416454 EXPECT_EQ("second response", response_data2);
16455}
16456
bncd16676a2016-07-20 16:23:0116457TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416458 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0916459 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216460 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916461 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216462 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416463
16464 HttpRequestInfo request;
16465 request.method = "POST";
16466 request.url = GURL("http://www.foo.com/");
16467 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016468 request.traffic_annotation =
16469 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416470
danakj1fd259a02016-04-16 03:17:0916471 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616472 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416473 // Send headers successfully, but get an error while sending the body.
16474 MockWrite data_writes[] = {
16475 MockWrite("POST / HTTP/1.1\r\n"
16476 "Host: www.foo.com\r\n"
16477 "Connection: keep-alive\r\n"
16478 "Content-Length: 3\r\n\r\n"
16479 "fo"),
16480 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16481 };
16482
16483 MockRead data_reads[] = {
16484 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16485 MockRead("hello world"),
16486 MockRead(SYNCHRONOUS, OK),
16487 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116488 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416489 session_deps_.socket_factory->AddSocketDataProvider(&data);
16490
16491 TestCompletionCallback callback;
16492
tfarina42834112016-09-22 13:38:2016493 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116494 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416495
16496 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116497 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416498
bnc691fda62016-08-12 00:43:1616499 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216500 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416501
wezca1070932016-05-26 20:30:5216502 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416503 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16504
16505 std::string response_data;
bnc691fda62016-08-12 00:43:1616506 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116507 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416508 EXPECT_EQ("hello world", response_data);
16509}
16510
16511// This tests the more common case than the previous test, where headers and
16512// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0116513TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0716514 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5416515
16516 HttpRequestInfo request;
16517 request.method = "POST";
16518 request.url = GURL("http://www.foo.com/");
16519 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016520 request.traffic_annotation =
16521 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416522
danakj1fd259a02016-04-16 03:17:0916523 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616524 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416525 // Send headers successfully, but get an error while sending the body.
16526 MockWrite data_writes[] = {
16527 MockWrite("POST / HTTP/1.1\r\n"
16528 "Host: www.foo.com\r\n"
16529 "Connection: keep-alive\r\n"
16530 "Transfer-Encoding: chunked\r\n\r\n"),
16531 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16532 };
16533
16534 MockRead data_reads[] = {
16535 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16536 MockRead("hello world"),
16537 MockRead(SYNCHRONOUS, OK),
16538 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116539 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416540 session_deps_.socket_factory->AddSocketDataProvider(&data);
16541
16542 TestCompletionCallback callback;
16543
tfarina42834112016-09-22 13:38:2016544 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116545 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416546 // Make sure the headers are sent before adding a chunk. This ensures that
16547 // they can't be merged with the body in a single send. Not currently
16548 // necessary since a chunked body is never merged with headers, but this makes
16549 // the test more future proof.
16550 base::RunLoop().RunUntilIdle();
16551
mmenkecbc2b712014-10-09 20:29:0716552 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5416553
16554 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116555 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416556
bnc691fda62016-08-12 00:43:1616557 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216558 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416559
wezca1070932016-05-26 20:30:5216560 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416561 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16562
16563 std::string response_data;
bnc691fda62016-08-12 00:43:1616564 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116565 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416566 EXPECT_EQ("hello world", response_data);
16567}
16568
bncd16676a2016-07-20 16:23:0116569TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916570 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216571 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916572 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216573 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416574
16575 HttpRequestInfo request;
16576 request.method = "POST";
16577 request.url = GURL("http://www.foo.com/");
16578 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016579 request.traffic_annotation =
16580 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416581
danakj1fd259a02016-04-16 03:17:0916582 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616583 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416584
16585 MockWrite data_writes[] = {
16586 MockWrite("POST / HTTP/1.1\r\n"
16587 "Host: www.foo.com\r\n"
16588 "Connection: keep-alive\r\n"
16589 "Content-Length: 3\r\n\r\n"),
16590 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16591 };
16592
16593 MockRead data_reads[] = {
16594 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16595 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
16596 MockRead("hello world"),
16597 MockRead(SYNCHRONOUS, OK),
16598 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116599 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416600 session_deps_.socket_factory->AddSocketDataProvider(&data);
16601
16602 TestCompletionCallback callback;
16603
tfarina42834112016-09-22 13:38:2016604 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116605 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416606
16607 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116608 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416609
bnc691fda62016-08-12 00:43:1616610 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5216611 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5416612
wezca1070932016-05-26 20:30:5216613 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5416614 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
16615
16616 std::string response_data;
bnc691fda62016-08-12 00:43:1616617 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0116618 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5416619 EXPECT_EQ("hello world", response_data);
16620}
16621
bncd16676a2016-07-20 16:23:0116622TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916623 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216624 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916625 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216626 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416627
16628 HttpRequestInfo request;
16629 request.method = "POST";
16630 request.url = GURL("http://www.foo.com/");
16631 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016632 request.traffic_annotation =
16633 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416634
danakj1fd259a02016-04-16 03:17:0916635 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616636 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416637 // Send headers successfully, but get an error while sending the body.
16638 MockWrite data_writes[] = {
16639 MockWrite("POST / HTTP/1.1\r\n"
16640 "Host: www.foo.com\r\n"
16641 "Connection: keep-alive\r\n"
16642 "Content-Length: 3\r\n\r\n"),
16643 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16644 };
16645
16646 MockRead data_reads[] = {
16647 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
16648 MockRead("hello world"),
16649 MockRead(SYNCHRONOUS, OK),
16650 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116651 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416652 session_deps_.socket_factory->AddSocketDataProvider(&data);
16653
16654 TestCompletionCallback callback;
16655
tfarina42834112016-09-22 13:38:2016656 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116657 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416658
16659 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116660 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416661}
16662
bncd16676a2016-07-20 16:23:0116663TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5416664 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0916665 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216666 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916667 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216668 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416669
16670 HttpRequestInfo request;
16671 request.method = "POST";
16672 request.url = GURL("http://www.foo.com/");
16673 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016674 request.traffic_annotation =
16675 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416676
danakj1fd259a02016-04-16 03:17:0916677 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616678 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416679 // Send headers successfully, but get an error while sending the body.
16680 MockWrite data_writes[] = {
16681 MockWrite("POST / HTTP/1.1\r\n"
16682 "Host: www.foo.com\r\n"
16683 "Connection: keep-alive\r\n"
16684 "Content-Length: 3\r\n\r\n"),
16685 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16686 };
16687
16688 MockRead data_reads[] = {
16689 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
16690 MockRead("HTTP/1.0 302 Redirect\r\n"),
16691 MockRead("Location: http://somewhere-else.com/\r\n"),
16692 MockRead("Content-Length: 0\r\n\r\n"),
16693 MockRead(SYNCHRONOUS, OK),
16694 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116695 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416696 session_deps_.socket_factory->AddSocketDataProvider(&data);
16697
16698 TestCompletionCallback callback;
16699
tfarina42834112016-09-22 13:38:2016700 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116701 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416702
16703 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116704 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416705}
16706
bncd16676a2016-07-20 16:23:0116707TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0916708 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216709 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916710 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216711 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416712
16713 HttpRequestInfo request;
16714 request.method = "POST";
16715 request.url = GURL("http://www.foo.com/");
16716 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016717 request.traffic_annotation =
16718 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416719
danakj1fd259a02016-04-16 03:17:0916720 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616721 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416722 // Send headers successfully, but get an error while sending the body.
16723 MockWrite data_writes[] = {
16724 MockWrite("POST / HTTP/1.1\r\n"
16725 "Host: www.foo.com\r\n"
16726 "Connection: keep-alive\r\n"
16727 "Content-Length: 3\r\n\r\n"),
16728 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16729 };
16730
16731 MockRead data_reads[] = {
16732 MockRead("HTTP 0.9 rocks!"),
16733 MockRead(SYNCHRONOUS, OK),
16734 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116735 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416736 session_deps_.socket_factory->AddSocketDataProvider(&data);
16737
16738 TestCompletionCallback callback;
16739
tfarina42834112016-09-22 13:38:2016740 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116741 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416742
16743 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116744 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416745}
16746
bncd16676a2016-07-20 16:23:0116747TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0916748 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2216749 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1916750 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2216751 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5416752
16753 HttpRequestInfo request;
16754 request.method = "POST";
16755 request.url = GURL("http://www.foo.com/");
16756 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1016757 request.traffic_annotation =
16758 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5416759
danakj1fd259a02016-04-16 03:17:0916760 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616761 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5416762 // Send headers successfully, but get an error while sending the body.
16763 MockWrite data_writes[] = {
16764 MockWrite("POST / HTTP/1.1\r\n"
16765 "Host: www.foo.com\r\n"
16766 "Connection: keep-alive\r\n"
16767 "Content-Length: 3\r\n\r\n"),
16768 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16769 };
16770
16771 MockRead data_reads[] = {
16772 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
16773 MockRead(SYNCHRONOUS, OK),
16774 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116775 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5416776 session_deps_.socket_factory->AddSocketDataProvider(&data);
16777
16778 TestCompletionCallback callback;
16779
tfarina42834112016-09-22 13:38:2016780 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116781 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5416782
16783 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116784 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5416785}
16786
Bence Békydca6bd92018-01-30 13:43:0616787#if BUILDFLAG(ENABLE_WEBSOCKETS)
16788
16789namespace {
16790
16791void AddWebSocketHeaders(HttpRequestHeaders* headers) {
16792 headers->SetHeader("Connection", "Upgrade");
16793 headers->SetHeader("Upgrade", "websocket");
16794 headers->SetHeader("Origin", "http://www.example.org");
16795 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0616796}
16797
16798} // namespace
16799
16800TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
Bence Béky2fcf4fa2018-04-06 20:06:0116801 for (bool secure : {true, false}) {
16802 MockWrite data_writes[] = {
16803 MockWrite("GET / HTTP/1.1\r\n"
16804 "Host: www.example.org\r\n"
16805 "Connection: Upgrade\r\n"
16806 "Upgrade: websocket\r\n"
16807 "Origin: http://www.example.org\r\n"
16808 "Sec-WebSocket-Version: 13\r\n"
16809 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
16810 "Sec-WebSocket-Extensions: permessage-deflate; "
16811 "client_max_window_bits\r\n\r\n")};
16812
16813 MockRead data_reads[] = {
16814 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
16815 "Upgrade: websocket\r\n"
16816 "Connection: Upgrade\r\n"
16817 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
16818
Ryan Sleevib8d7ea02018-05-07 20:01:0116819 StaticSocketDataProvider data(data_reads, data_writes);
Bence Béky2fcf4fa2018-04-06 20:06:0116820 session_deps_.socket_factory->AddSocketDataProvider(&data);
16821 SSLSocketDataProvider ssl(ASYNC, OK);
16822 if (secure)
16823 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
Bence Békydca6bd92018-01-30 13:43:0616824
16825 HttpRequestInfo request;
16826 request.method = "GET";
Bence Béky2fcf4fa2018-04-06 20:06:0116827 request.url =
16828 GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
16829 AddWebSocketHeaders(&request.extra_headers);
Ramin Halavatib5e433e2018-02-07 07:41:1016830 request.traffic_annotation =
16831 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0616832
Bence Béky2fcf4fa2018-04-06 20:06:0116833 TestWebSocketHandshakeStreamCreateHelper
16834 websocket_handshake_stream_create_helper;
Bence Béky8d1c6052018-02-07 12:48:1516835
Bence Béky2fcf4fa2018-04-06 20:06:0116836 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Bence Békydca6bd92018-01-30 13:43:0616837 HttpNetworkTransaction trans(LOW, session.get());
16838 trans.SetWebSocketHandshakeStreamCreateHelper(
Bence Béky2fcf4fa2018-04-06 20:06:0116839 &websocket_handshake_stream_create_helper);
Bence Békydca6bd92018-01-30 13:43:0616840
16841 TestCompletionCallback callback;
Bence Béky2fcf4fa2018-04-06 20:06:0116842 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
16843 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Bence Békydca6bd92018-01-30 13:43:0616844
Bence Béky2fcf4fa2018-04-06 20:06:0116845 const HttpStreamRequest* stream_request = trans.stream_request_.get();
16846 ASSERT_TRUE(stream_request);
16847 EXPECT_EQ(&websocket_handshake_stream_create_helper,
16848 stream_request->websocket_handshake_stream_create_helper());
16849
16850 rv = callback.WaitForResult();
16851 EXPECT_THAT(rv, IsOk());
16852
16853 EXPECT_TRUE(data.AllReadDataConsumed());
16854 EXPECT_TRUE(data.AllWriteDataConsumed());
Bence Békydca6bd92018-01-30 13:43:0616855 }
16856}
16857
Adam Rice425cf122015-01-19 06:18:2416858// Verify that proxy headers are not sent to the destination server when
16859// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0116860TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2416861 HttpRequestInfo request;
16862 request.method = "GET";
bncce36dca22015-04-21 22:11:2316863 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016864 request.traffic_annotation =
16865 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2416866 AddWebSocketHeaders(&request.extra_headers);
16867
16868 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5916869 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4916870 ProxyResolutionService::CreateFixedFromPacResult(
16871 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2416872
danakj1fd259a02016-04-16 03:17:0916873 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416874
16875 // Since a proxy is configured, try to establish a tunnel.
16876 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1716877 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16878 "Host: www.example.org:443\r\n"
16879 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416880
16881 // After calling trans->RestartWithAuth(), this is the request we should
16882 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1716883 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
16884 "Host: www.example.org:443\r\n"
16885 "Proxy-Connection: keep-alive\r\n"
16886 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416887
rsleevidb16bb02015-11-12 23:47:1716888 MockWrite("GET / HTTP/1.1\r\n"
16889 "Host: www.example.org\r\n"
16890 "Connection: Upgrade\r\n"
16891 "Upgrade: websocket\r\n"
16892 "Origin: http://www.example.org\r\n"
16893 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1516894 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
16895 "Sec-WebSocket-Extensions: permessage-deflate; "
16896 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2416897
16898 // The proxy responds to the connect with a 407, using a persistent
16899 // connection.
16900 MockRead data_reads[] = {
16901 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1516902 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
16903 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
16904 "Content-Length: 0\r\n"
16905 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416906
16907 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
16908
Bence Béky8d1c6052018-02-07 12:48:1516909 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
16910 "Upgrade: websocket\r\n"
16911 "Connection: Upgrade\r\n"
16912 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2416913
Ryan Sleevib8d7ea02018-05-07 20:01:0116914 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2416915 session_deps_.socket_factory->AddSocketDataProvider(&data);
16916 SSLSocketDataProvider ssl(ASYNC, OK);
16917 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16918
Bence Béky8d1c6052018-02-07 12:48:1516919 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
16920
bnc87dcefc2017-05-25 12:47:5816921 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916922 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2416923 trans->SetWebSocketHandshakeStreamCreateHelper(
16924 &websocket_stream_create_helper);
16925
16926 {
16927 TestCompletionCallback callback;
16928
tfarina42834112016-09-22 13:38:2016929 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116930 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416931
16932 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116933 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416934 }
16935
16936 const HttpResponseInfo* response = trans->GetResponseInfo();
16937 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216938 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416939 EXPECT_EQ(407, response->headers->response_code());
16940
16941 {
16942 TestCompletionCallback callback;
16943
16944 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
16945 callback.callback());
robpercival214763f2016-07-01 23:27:0116946 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2416947
16948 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116949 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2416950 }
16951
16952 response = trans->GetResponseInfo();
16953 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5216954 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2416955
16956 EXPECT_EQ(101, response->headers->response_code());
16957
16958 trans.reset();
16959 session->CloseAllConnections();
16960}
16961
16962// Verify that proxy headers are not sent to the destination server when
16963// establishing a tunnel for an insecure WebSocket connection.
16964// This requires the authentication info to be injected into the auth cache
16965// due to crbug.com/395064
16966// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0116967TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2416968 HttpRequestInfo request;
16969 request.method = "GET";
bncce36dca22015-04-21 22:11:2316970 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1016971 request.traffic_annotation =
16972 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2416973 AddWebSocketHeaders(&request.extra_headers);
16974
16975 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5916976 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4916977 ProxyResolutionService::CreateFixedFromPacResult(
16978 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2416979
danakj1fd259a02016-04-16 03:17:0916980 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2416981
16982 MockWrite data_writes[] = {
16983 // Try to establish a tunnel for the WebSocket connection, with
16984 // credentials. Because WebSockets have a separate set of socket pools,
16985 // they cannot and will not use the same TCP/IP connection as the
16986 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1516987 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
16988 "Host: www.example.org:80\r\n"
16989 "Proxy-Connection: keep-alive\r\n"
16990 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2416991
Bence Béky8d1c6052018-02-07 12:48:1516992 MockWrite("GET / HTTP/1.1\r\n"
16993 "Host: www.example.org\r\n"
16994 "Connection: Upgrade\r\n"
16995 "Upgrade: websocket\r\n"
16996 "Origin: http://www.example.org\r\n"
16997 "Sec-WebSocket-Version: 13\r\n"
16998 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
16999 "Sec-WebSocket-Extensions: permessage-deflate; "
17000 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417001
17002 MockRead data_reads[] = {
17003 // HTTP CONNECT with credentials.
17004 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17005
17006 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1517007 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17008 "Upgrade: websocket\r\n"
17009 "Connection: Upgrade\r\n"
17010 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417011
Ryan Sleevib8d7ea02018-05-07 20:01:0117012 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417013 session_deps_.socket_factory->AddSocketDataProvider(&data);
17014
17015 session->http_auth_cache()->Add(
17016 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
17017 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17018
Bence Béky8d1c6052018-02-07 12:48:1517019 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17020
bnc87dcefc2017-05-25 12:47:5817021 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917022 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417023 trans->SetWebSocketHandshakeStreamCreateHelper(
17024 &websocket_stream_create_helper);
17025
17026 TestCompletionCallback callback;
17027
tfarina42834112016-09-22 13:38:2017028 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117029 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417030
17031 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117032 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417033
17034 const HttpResponseInfo* response = trans->GetResponseInfo();
17035 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217036 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417037
17038 EXPECT_EQ(101, response->headers->response_code());
17039
17040 trans.reset();
17041 session->CloseAllConnections();
17042}
17043
Bence Békydca6bd92018-01-30 13:43:0617044#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
17045
bncd16676a2016-07-20 16:23:0117046TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917047 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217048 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917049 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217050 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217051
17052 HttpRequestInfo request;
17053 request.method = "POST";
17054 request.url = GURL("http://www.foo.com/");
17055 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017056 request.traffic_annotation =
17057 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217058
danakj1fd259a02016-04-16 03:17:0917059 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617060 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217061 MockWrite data_writes[] = {
17062 MockWrite("POST / HTTP/1.1\r\n"
17063 "Host: www.foo.com\r\n"
17064 "Connection: keep-alive\r\n"
17065 "Content-Length: 3\r\n\r\n"),
17066 MockWrite("foo"),
17067 };
17068
17069 MockRead data_reads[] = {
17070 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17071 MockRead(SYNCHRONOUS, OK),
17072 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117073 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217074 session_deps_.socket_factory->AddSocketDataProvider(&data);
17075
17076 TestCompletionCallback callback;
17077
17078 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017079 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117080 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217081
17082 std::string response_data;
bnc691fda62016-08-12 00:43:1617083 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217084
Ryan Sleevib8d7ea02018-05-07 20:01:0117085 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17086 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217087}
17088
bncd16676a2016-07-20 16:23:0117089TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917090 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217091 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917092 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217093 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217094
17095 HttpRequestInfo request;
17096 request.method = "POST";
17097 request.url = GURL("http://www.foo.com/");
17098 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017099 request.traffic_annotation =
17100 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217101
danakj1fd259a02016-04-16 03:17:0917102 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617103 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217104 MockWrite data_writes[] = {
17105 MockWrite("POST / HTTP/1.1\r\n"
17106 "Host: www.foo.com\r\n"
17107 "Connection: keep-alive\r\n"
17108 "Content-Length: 3\r\n\r\n"),
17109 MockWrite("foo"),
17110 };
17111
17112 MockRead data_reads[] = {
17113 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
17114 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17115 MockRead(SYNCHRONOUS, OK),
17116 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117117 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217118 session_deps_.socket_factory->AddSocketDataProvider(&data);
17119
17120 TestCompletionCallback callback;
17121
17122 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017123 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117124 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217125
17126 std::string response_data;
bnc691fda62016-08-12 00:43:1617127 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217128
Ryan Sleevib8d7ea02018-05-07 20:01:0117129 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17130 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217131}
17132
bncd16676a2016-07-20 16:23:0117133TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2217134 ChunkedUploadDataStream upload_data_stream(0);
17135
17136 HttpRequestInfo request;
17137 request.method = "POST";
17138 request.url = GURL("http://www.foo.com/");
17139 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e2018-02-07 07:41:1017140 request.traffic_annotation =
17141 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217142
danakj1fd259a02016-04-16 03:17:0917143 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617144 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217145 // Send headers successfully, but get an error while sending the body.
17146 MockWrite data_writes[] = {
17147 MockWrite("POST / HTTP/1.1\r\n"
17148 "Host: www.foo.com\r\n"
17149 "Connection: keep-alive\r\n"
17150 "Transfer-Encoding: chunked\r\n\r\n"),
17151 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
17152 };
17153
17154 MockRead data_reads[] = {
17155 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17156 MockRead(SYNCHRONOUS, OK),
17157 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117158 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217159 session_deps_.socket_factory->AddSocketDataProvider(&data);
17160
17161 TestCompletionCallback callback;
17162
17163 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017164 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2217165
17166 base::RunLoop().RunUntilIdle();
17167 upload_data_stream.AppendData("f", 1, false);
17168
17169 base::RunLoop().RunUntilIdle();
17170 upload_data_stream.AppendData("oo", 2, true);
17171
robpercival214763f2016-07-01 23:27:0117172 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217173
17174 std::string response_data;
bnc691fda62016-08-12 00:43:1617175 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217176
Ryan Sleevib8d7ea02018-05-07 20:01:0117177 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17178 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217179}
17180
eustasc7d27da2017-04-06 10:33:2017181void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
17182 const std::string& accept_encoding,
17183 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0317184 const std::string& location,
eustasc7d27da2017-04-06 10:33:2017185 bool should_match) {
17186 HttpRequestInfo request;
17187 request.method = "GET";
17188 request.url = GURL("http://www.foo.com/");
17189 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
17190 accept_encoding);
Ramin Halavatib5e433e2018-02-07 07:41:1017191 request.traffic_annotation =
17192 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2017193
17194 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
17195 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17196 // Send headers successfully, but get an error while sending the body.
17197 MockWrite data_writes[] = {
17198 MockWrite("GET / HTTP/1.1\r\n"
17199 "Host: www.foo.com\r\n"
17200 "Connection: keep-alive\r\n"
17201 "Accept-Encoding: "),
17202 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
17203 };
17204
sky50576f32017-05-01 19:28:0317205 std::string response_code = "200 OK";
17206 std::string extra;
17207 if (!location.empty()) {
17208 response_code = "301 Redirect\r\nLocation: ";
17209 response_code.append(location);
17210 }
17211
eustasc7d27da2017-04-06 10:33:2017212 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0317213 MockRead("HTTP/1.0 "),
17214 MockRead(response_code.data()),
17215 MockRead("\r\nContent-Encoding: "),
17216 MockRead(content_encoding.data()),
17217 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2017218 MockRead(SYNCHRONOUS, OK),
17219 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117220 StaticSocketDataProvider data(data_reads, data_writes);
eustasc7d27da2017-04-06 10:33:2017221 session_deps->socket_factory->AddSocketDataProvider(&data);
17222
17223 TestCompletionCallback callback;
17224
17225 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17226 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17227
17228 rv = callback.WaitForResult();
17229 if (should_match) {
17230 EXPECT_THAT(rv, IsOk());
17231 } else {
17232 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
17233 }
17234}
17235
17236TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0317237 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2017238}
17239
17240TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0317241 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
17242 true);
eustasc7d27da2017-04-06 10:33:2017243}
17244
17245TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
17246 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0317247 "", false);
17248}
17249
17250TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
17251 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
17252 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2017253}
17254
xunjieli96f2a402017-06-05 17:24:2717255TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
17256 ProxyConfig proxy_config;
17257 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17258 proxy_config.set_pac_mandatory(true);
17259 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917260 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4917261 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
17262 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Bence Béky8f9d7d3952017-10-09 19:58:0417263 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2717264
17265 HttpRequestInfo request;
17266 request.method = "GET";
17267 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017268 request.traffic_annotation =
17269 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717270
17271 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17272 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17273
17274 TestCompletionCallback callback;
17275
17276 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17277 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17278 EXPECT_THAT(callback.WaitForResult(),
17279 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17280}
17281
17282TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
17283 ProxyConfig proxy_config;
17284 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
17285 proxy_config.set_pac_mandatory(true);
17286 MockAsyncProxyResolverFactory* proxy_resolver_factory =
17287 new MockAsyncProxyResolverFactory(false);
17288 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5917289 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4917290 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
17291 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Lily Houghton8c2f97d2018-01-22 05:06:5917292 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2717293 HttpRequestInfo request;
17294 request.method = "GET";
17295 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017296 request.traffic_annotation =
17297 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717298
17299 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17300 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17301
17302 TestCompletionCallback callback;
17303 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17304 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17305
17306 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
17307 ERR_FAILED, &resolver);
17308 EXPECT_THAT(callback.WaitForResult(),
17309 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
17310}
17311
17312TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5917313 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917314 ProxyResolutionService::CreateFixedFromPacResult(
17315 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717316 session_deps_.enable_quic = false;
17317 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17318
17319 HttpRequestInfo request;
17320 request.method = "GET";
17321 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e2018-02-07 07:41:1017322 request.traffic_annotation =
17323 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2717324
17325 TestCompletionCallback callback;
17326 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17327 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17328 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17329
17330 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
17331}
17332
Douglas Creager3cb042052018-11-06 23:08:5217333//-----------------------------------------------------------------------------
Douglas Creager134b52e2018-11-09 18:00:1417334// Reporting tests
17335
17336#if BUILDFLAG(ENABLE_REPORTING)
17337class HttpNetworkTransactionReportingTest : public HttpNetworkTransactionTest {
17338 protected:
17339 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3617340 HttpNetworkTransactionTest::SetUp();
Douglas Creager134b52e2018-11-09 18:00:1417341 auto test_reporting_context = std::make_unique<TestReportingContext>(
17342 &clock_, &tick_clock_, ReportingPolicy());
17343 test_reporting_context_ = test_reporting_context.get();
17344 session_deps_.reporting_service =
17345 ReportingService::CreateForTesting(std::move(test_reporting_context));
17346 }
17347
17348 TestReportingContext* reporting_context() const {
17349 return test_reporting_context_;
17350 }
17351
17352 void clear_reporting_service() {
17353 session_deps_.reporting_service.reset();
17354 test_reporting_context_ = nullptr;
17355 }
17356
17357 // Makes an HTTPS request that should install a valid Reporting policy.
17358 void RequestPolicy() {
17359 MockRead data_reads[] = {
17360 MockRead("HTTP/1.0 200 OK\r\n"),
17361 MockRead("Report-To: {\"group\": \"nel\", \"max_age\": 86400, "
17362 "\"endpoints\": [{\"url\": "
17363 "\"https://www.example.org/upload/\"}]}\r\n"),
17364 MockRead("\r\n"),
17365 MockRead("hello world"),
17366 MockRead(SYNCHRONOUS, OK),
17367 };
17368 MockWrite data_writes[] = {
17369 MockWrite("GET / HTTP/1.1\r\n"
17370 "Host: www.example.org\r\n"
17371 "Connection: keep-alive\r\n\r\n"),
17372 };
17373
17374 HttpRequestInfo request;
17375 request.method = "GET";
17376 request.url = GURL(url_);
17377 request.traffic_annotation =
17378 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17379
17380 SSLSocketDataProvider ssl(ASYNC, OK);
17381 if (request.url.SchemeIsCryptographic()) {
17382 ssl.ssl_info.cert =
17383 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
17384 ASSERT_TRUE(ssl.ssl_info.cert);
17385 ssl.ssl_info.cert_status = cert_status_;
17386 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17387 }
17388
17389 StaticSocketDataProvider reads(data_reads, data_writes);
17390 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17391
17392 TestCompletionCallback callback;
17393 auto session = CreateSession(&session_deps_);
17394 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17395 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17396 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17397 EXPECT_THAT(callback.WaitForResult(), IsOk());
17398 }
17399
17400 protected:
17401 std::string url_ = "https://www.example.org/";
17402 CertStatus cert_status_ = 0;
17403
17404 private:
17405 TestReportingContext* test_reporting_context_;
17406};
17407
17408TEST_F(HttpNetworkTransactionReportingTest,
17409 DontProcessReportToHeaderNoService) {
17410 base::HistogramTester histograms;
17411 clear_reporting_service();
17412 RequestPolicy();
17413 histograms.ExpectBucketCount(
17414 ReportingHeaderParser::kHeaderOutcomeHistogram,
17415 ReportingHeaderParser::HeaderOutcome::DISCARDED_NO_REPORTING_SERVICE, 1);
17416}
17417
17418TEST_F(HttpNetworkTransactionReportingTest, DontProcessReportToHeaderHttp) {
17419 base::HistogramTester histograms;
17420 url_ = "http://www.example.org/";
17421 RequestPolicy();
17422 histograms.ExpectBucketCount(
17423 ReportingHeaderParser::kHeaderOutcomeHistogram,
17424 ReportingHeaderParser::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
17425}
17426
17427TEST_F(HttpNetworkTransactionReportingTest, ProcessReportToHeaderHttps) {
17428 RequestPolicy();
17429 std::vector<const ReportingClient*> clients;
17430 reporting_context()->cache()->GetClients(&clients);
17431 ASSERT_EQ(1u, clients.size());
17432 const auto* client = clients[0];
17433 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
17434 client->origin);
17435 EXPECT_EQ(GURL("https://www.example.org/upload/"), client->endpoint);
17436 EXPECT_EQ("nel", client->group);
17437}
17438
17439TEST_F(HttpNetworkTransactionReportingTest,
17440 DontProcessReportToHeaderInvalidHttps) {
17441 base::HistogramTester histograms;
17442 cert_status_ = CERT_STATUS_COMMON_NAME_INVALID;
17443 RequestPolicy();
17444 histograms.ExpectBucketCount(
17445 ReportingHeaderParser::kHeaderOutcomeHistogram,
17446 ReportingHeaderParser::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR, 1);
17447}
17448#endif // BUILDFLAG(ENABLE_REPORTING)
17449
17450//-----------------------------------------------------------------------------
Douglas Creager3cb042052018-11-06 23:08:5217451// Network Error Logging tests
17452
17453#if BUILDFLAG(ENABLE_REPORTING)
17454class HttpNetworkTransactionNetworkErrorLoggingTest
17455 : public HttpNetworkTransactionTest {
17456 protected:
17457 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3617458 HttpNetworkTransactionTest::SetUp();
Douglas Creager3cb042052018-11-06 23:08:5217459 auto network_error_logging_service =
17460 std::make_unique<TestNetworkErrorLoggingService>();
17461 test_network_error_logging_service_ = network_error_logging_service.get();
17462 session_deps_.network_error_logging_service =
17463 std::move(network_error_logging_service);
17464 }
17465
17466 TestNetworkErrorLoggingService* network_error_logging_service() const {
17467 return test_network_error_logging_service_;
17468 }
17469
17470 void clear_network_error_logging_service() {
17471 session_deps_.network_error_logging_service.reset();
17472 test_network_error_logging_service_ = nullptr;
17473 }
17474
17475 // Makes an HTTPS request that should install a valid NEL policy.
17476 void RequestPolicy() {
Douglas Creageref5eecdc2018-11-09 20:50:3617477 std::string extra_header_string = extra_headers_.ToString();
Douglas Creager3cb042052018-11-06 23:08:5217478 MockRead data_reads[] = {
17479 MockRead("HTTP/1.0 200 OK\r\n"),
17480 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
17481 MockRead("\r\n"),
17482 MockRead("hello world"),
17483 MockRead(SYNCHRONOUS, OK),
17484 };
17485 MockWrite data_writes[] = {
17486 MockWrite("GET / HTTP/1.1\r\n"
17487 "Host: www.example.org\r\n"
Douglas Creageref5eecdc2018-11-09 20:50:3617488 "Connection: keep-alive\r\n"),
17489 MockWrite(ASYNC, extra_header_string.data(),
17490 extra_header_string.size()),
Douglas Creager3cb042052018-11-06 23:08:5217491 };
17492
17493 HttpRequestInfo request;
17494 request.method = "GET";
17495 request.url = GURL(url_);
Douglas Creageref5eecdc2018-11-09 20:50:3617496 request.extra_headers = extra_headers_;
17497 request.reporting_upload_depth = reporting_upload_depth_;
Douglas Creager3cb042052018-11-06 23:08:5217498 request.traffic_annotation =
17499 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17500
17501 SSLSocketDataProvider ssl(ASYNC, OK);
17502 if (request.url.SchemeIsCryptographic()) {
17503 ssl.ssl_info.cert =
17504 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
17505 ASSERT_TRUE(ssl.ssl_info.cert);
17506 ssl.ssl_info.cert_status = cert_status_;
17507 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17508 }
17509
17510 StaticSocketDataProvider reads(data_reads, data_writes);
17511 session_deps_.socket_factory->AddSocketDataProvider(&reads);
17512
17513 TestCompletionCallback callback;
17514 auto session = CreateSession(&session_deps_);
17515 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
17516 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17517 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17518 EXPECT_THAT(callback.WaitForResult(), IsOk());
17519 }
17520
17521 protected:
17522 std::string url_ = "https://www.example.org/";
17523 CertStatus cert_status_ = 0;
Douglas Creageref5eecdc2018-11-09 20:50:3617524 HttpRequestHeaders extra_headers_;
17525 int reporting_upload_depth_ = 0;
Douglas Creager3cb042052018-11-06 23:08:5217526
17527 private:
17528 TestNetworkErrorLoggingService* test_network_error_logging_service_;
17529};
17530
17531TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
17532 DontProcessNelHeaderNoService) {
17533 base::HistogramTester histograms;
17534 clear_network_error_logging_service();
17535 RequestPolicy();
17536 histograms.ExpectBucketCount(
17537 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
17538 NetworkErrorLoggingService::HeaderOutcome::
17539 DISCARDED_NO_NETWORK_ERROR_LOGGING_SERVICE,
17540 1);
17541}
17542
17543TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
17544 DontProcessNelHeaderHttp) {
17545 base::HistogramTester histograms;
17546 url_ = "http://www.example.org/";
17547 RequestPolicy();
17548 histograms.ExpectBucketCount(
17549 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
17550 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
17551}
17552
17553TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ProcessNelHeaderHttps) {
17554 RequestPolicy();
17555 ASSERT_EQ(1u, network_error_logging_service()->headers().size());
17556 const auto& header = network_error_logging_service()->headers()[0];
17557 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
17558 header.origin);
17559 EXPECT_EQ(IPAddress::IPv4Localhost(), header.received_ip_address);
17560 EXPECT_EQ("{\"report_to\": \"nel\", \"max_age\": 86400}", header.value);
17561}
17562
17563TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
17564 DontProcessNelHeaderInvalidHttps) {
17565 base::HistogramTester histograms;
17566 cert_status_ = CERT_STATUS_COMMON_NAME_INVALID;
17567 RequestPolicy();
17568 histograms.ExpectBucketCount(
17569 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
17570 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR,
17571 1);
17572}
Douglas Creageref5eecdc2018-11-09 20:50:3617573
17574TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, CreateReportHttps) {
17575 RequestPolicy();
17576 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
17577 const auto& error = network_error_logging_service()->errors()[0];
17578 EXPECT_EQ(GURL("https://www.example.org/"), error.uri);
17579 EXPECT_TRUE(error.referrer.is_empty());
17580 EXPECT_EQ("", error.user_agent);
17581 EXPECT_EQ(IPAddress::IPv4Localhost(), error.server_ip);
17582 EXPECT_EQ("http/1.1", error.protocol);
17583 EXPECT_EQ("GET", error.method);
17584 EXPECT_EQ(200, error.status_code);
17585 EXPECT_EQ(OK, error.type);
17586 EXPECT_EQ(0, error.reporting_upload_depth);
17587}
17588
17589TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ReportContainsReferrer) {
17590 constexpr char kReferrer[] = "https://www.example.org/login/";
17591 extra_headers_.SetHeader("Referer", kReferrer);
17592 RequestPolicy();
17593 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
17594 const auto& error = network_error_logging_service()->errors()[0];
17595 EXPECT_EQ(GURL(kReferrer), error.referrer);
17596}
17597
17598TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
17599 ReportContainsUploadDepth) {
17600 reporting_upload_depth_ = 7;
17601 RequestPolicy();
17602 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
17603 const auto& error = network_error_logging_service()->errors()[0];
17604 EXPECT_EQ(7, error.reporting_upload_depth);
17605}
17606
17607TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ReportContainsUserAgent) {
17608 constexpr char kUserAgent[] = "Mozilla/1.0";
17609 extra_headers_.SetHeader("User-Agent", kUserAgent);
17610 RequestPolicy();
17611 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
17612 const auto& error = network_error_logging_service()->errors()[0];
17613 EXPECT_EQ(kUserAgent, error.user_agent);
17614}
Douglas Creager3cb042052018-11-06 23:08:5217615#endif // BUILDFLAG(ENABLE_REPORTING)
17616
[email protected]89ceba9a2009-03-21 03:46:0617617} // namespace net