blob: d2d72e5636d5cd9409ebec35582bbffca721e32d [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
Sebastien Marchand6d0558fd2019-01-25 16:49:3717#include "base/bind.h"
[email protected]68bf9152008-09-25 19:47:3018#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5219#include "base/files/file_path.h"
thestigd8df0332014-09-04 06:33:2920#include "base/files/file_util.h"
[email protected]f3da152d2012-06-02 01:00:5721#include "base/json/json_writer.h"
Adam Rice425cf122015-01-19 06:18:2422#include "base/logging.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"
Eric Orthf4db66a2019-02-19 21:35:3325#include "base/optional.h"
[email protected]a34f61ee2014-03-18 20:59:4926#include "base/run_loop.h"
Avi Drissman4365a4782018-12-28 19:26:2427#include "base/stl_util.h"
Bence Békyd74f4382018-02-20 18:26:1928#include "base/strings/string_piece.h"
[email protected]125ef482013-06-11 18:32:4729#include "base/strings/string_util.h"
Matt Menked732ea42019-03-08 12:05:0030#include "base/strings/stringprintf.h"
[email protected]750b2f3c2013-06-07 18:41:0531#include "base/strings/utf_string_conversions.h"
Douglas Creager3cb042052018-11-06 23:08:5232#include "base/test/metrics/histogram_tester.h"
Matt Menkeecfecfc72019-02-05 19:15:2833#include "base/test/scoped_task_environment.h"
Douglas Creager134b52e2018-11-09 18:00:1434#include "base/test/simple_test_clock.h"
35#include "base/test/simple_test_tick_clock.h"
[email protected]f36a8132011-09-02 18:36:3336#include "base/test/test_file_util.h"
gabf767595f2016-05-11 18:50:3537#include "base/threading/thread_task_runner_handle.h"
[email protected]277d5942010-08-11 21:02:3538#include "net/base/auth.h"
mmenkecbc2b712014-10-09 20:29:0739#include "net/base/chunked_upload_data_stream.h"
Bence Békya25e3f72018-02-13 21:13:3940#include "net/base/completion_once_callback.h"
mmenkecbc2b712014-10-09 20:29:0741#include "net/base/elements_upload_data_stream.h"
Eric Orthf4db66a2019-02-19 21:35:3342#include "net/base/host_port_pair.h"
Tsuyoshi Horo01faed62019-02-20 22:11:3743#include "net/base/ip_endpoint.h"
[email protected]58e32bb2013-01-21 18:23:2544#include "net/base/load_timing_info.h"
45#include "net/base/load_timing_info_test_util.h"
Adam Rice425cf122015-01-19 06:18:2446#include "net/base/net_errors.h"
Matt Menkebdf777802019-04-22 19:38:5947#include "net/base/privacy_mode.h"
tbansal28e68f82016-02-04 02:56:1548#include "net/base/proxy_delegate.h"
Lily Houghton582d4622018-01-22 22:43:4049#include "net/base/proxy_server.h"
[email protected]ac790b42009-12-02 04:31:3150#include "net/base/request_priority.h"
initial.commit586acc5fe2008-07-26 22:42:5251#include "net/base/test_completion_callback.h"
tbansal28e68f82016-02-04 02:56:1552#include "net/base/test_proxy_delegate.h"
[email protected]b2d26cfd2012-12-11 10:36:0653#include "net/base/upload_bytes_element_reader.h"
[email protected]d98961652012-09-11 20:27:2154#include "net/base/upload_file_element_reader.h"
Bence Béky230ac612017-08-30 19:17:0855#include "net/cert/cert_status_flags.h"
[email protected]6e7845ae2013-03-29 21:48:1156#include "net/cert/mock_cert_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5357#include "net/dns/mock_host_resolver.h"
[email protected]df41d0d82014-03-13 00:43:2458#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]3c32c5f2010-05-18 15:18:1259#include "net/http/http_auth_handler_digest.h"
[email protected]3fd9dae2010-06-21 11:39:0060#include "net/http/http_auth_handler_mock.h"
[email protected]385a4672009-03-11 22:21:2961#include "net/http/http_auth_handler_ntlm.h"
aberentbba302d2015-12-03 10:20:1962#include "net/http/http_auth_scheme.h"
[email protected]0877e3d2009-10-17 22:29:5763#include "net/http/http_basic_stream.h"
initial.commit586acc5fe2008-07-26 22:42:5264#include "net/http/http_network_session.h"
[email protected]87bfa3f2010-09-30 14:54:5665#include "net/http/http_network_session_peer.h"
Matt Menke6e879bd2019-03-18 17:26:0466#include "net/http/http_proxy_connect_job.h"
Adam Rice425cf122015-01-19 06:18:2467#include "net/http/http_request_headers.h"
mmenke5f94fda2016-06-02 20:54:1368#include "net/http/http_response_info.h"
[email protected]17291a022011-10-10 07:32:5369#include "net/http/http_server_properties_impl.h"
[email protected]0877e3d2009-10-17 22:29:5770#include "net/http/http_stream.h"
[email protected]8e6441ca2010-08-19 05:56:3871#include "net/http/http_stream_factory.h"
[email protected]c41737d2014-05-14 07:47:1972#include "net/http/http_transaction_test_util.h"
eroman87c53d62015-04-02 06:51:0773#include "net/log/net_log.h"
mikecirone8b85c432016-09-08 19:11:0074#include "net/log/net_log_event_type.h"
mikecironef22f9812016-10-04 03:40:1975#include "net/log/net_log_source.h"
vishal.b62985ca92015-04-17 08:45:5176#include "net/log/test_net_log.h"
mmenke43758e62015-05-04 21:09:4677#include "net/log/test_net_log_entry.h"
78#include "net/log/test_net_log_util.h"
Lily Houghton582d4622018-01-22 22:43:4079#include "net/proxy_resolution/mock_proxy_resolver.h"
80#include "net/proxy_resolution/proxy_config_service_fixed.h"
81#include "net/proxy_resolution/proxy_info.h"
Lily Houghtonffe89daa02018-03-09 18:30:0382#include "net/proxy_resolution/proxy_resolution_service.h"
Lily Houghton582d4622018-01-22 22:43:4083#include "net/proxy_resolution/proxy_resolver.h"
84#include "net/proxy_resolution/proxy_resolver_factory.h"
[email protected]f7984fc62009-06-22 23:26:4485#include "net/socket/client_socket_factory.h"
mmenked3641e12016-01-28 16:06:1586#include "net/socket/client_socket_pool.h"
[email protected]483fa202013-05-14 01:07:0387#include "net/socket/client_socket_pool_manager.h"
Matt Menked6fd2a52019-03-20 06:14:3688#include "net/socket/connect_job.h"
ttuttle1f2d7e92015-04-28 16:17:4789#include "net/socket/connection_attempts.h"
[email protected]a42dbd142011-11-17 16:42:0290#include "net/socket/mock_client_socket_pool_manager.h"
[email protected]bb88e1d32013-05-03 23:11:0791#include "net/socket/next_proto.h"
Paul Jensena457017a2018-01-19 23:52:0492#include "net/socket/socket_tag.h"
[email protected]f7984fc62009-06-22 23:26:4493#include "net/socket/socket_test_util.h"
Matt Menke4b412da2019-01-25 19:31:1294#include "net/socket/socks_connect_job.h"
[email protected]f7984fc62009-06-22 23:26:4495#include "net/socket/ssl_client_socket.h"
Bence Béky94658bf2018-05-11 19:22:5896#include "net/spdy/spdy_session.h"
97#include "net/spdy/spdy_session_pool.h"
98#include "net/spdy/spdy_test_util_common.h"
[email protected]536fd0b2013-03-14 17:41:5799#include "net/ssl/ssl_cert_request_info.h"
[email protected]e86839fd2013-08-14 18:29:03100#include "net/ssl/ssl_config_service.h"
[email protected]536fd0b2013-03-14 17:41:57101#include "net/ssl/ssl_info.h"
svaldez7872fd02015-11-19 21:10:54102#include "net/ssl/ssl_private_key.h"
[email protected]6e7845ae2013-03-29 21:48:11103#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:01104#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:43105#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:01106#include "net/test/test_with_scoped_task_environment.h"
Victor Vasiliev27cc7712019-01-24 11:50:14107#include "net/third_party/quiche/src/spdy/core/spdy_framer.h"
[email protected]baee31a2018-01-18 06:10:23108#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
Matt Menked732ea42019-03-08 12:05:00109#include "net/url_request/static_http_user_agent_settings.h"
[email protected]831e4a32013-11-14 02:14:44110#include "net/websockets/websocket_handshake_stream_base.h"
Bence Békydca6bd92018-01-30 13:43:06111#include "net/websockets/websocket_test_util.h"
bncf4588402015-11-24 13:33:18112#include "testing/gmock/include/gmock/gmock.h"
initial.commit586acc5fe2008-07-26 22:42:52113#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:15114#include "testing/platform_test.h"
[email protected]795cbf82013-07-22 09:37:27115#include "url/gurl.h"
initial.commit586acc5fe2008-07-26 22:42:52116
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37117#if defined(NTLM_PORTABLE)
118#include "base/base64.h"
119#include "net/ntlm/ntlm_test_data.h"
120#endif
121
Douglas Creager3cb042052018-11-06 23:08:52122#if BUILDFLAG(ENABLE_REPORTING)
123#include "net/network_error_logging/network_error_logging_service.h"
124#include "net/network_error_logging/network_error_logging_test_util.h"
Douglas Creager134b52e2018-11-09 18:00:14125#include "net/reporting/reporting_cache.h"
126#include "net/reporting/reporting_client.h"
127#include "net/reporting/reporting_header_parser.h"
128#include "net/reporting/reporting_service.h"
129#include "net/reporting/reporting_test_util.h"
Douglas Creager3cb042052018-11-06 23:08:52130#endif // BUILDFLAG(ENABLE_REPORTING)
131
robpercival214763f2016-07-01 23:27:01132using net::test::IsError;
133using net::test::IsOk;
134
[email protected]ad65a3e2013-12-25 18:18:01135using base::ASCIIToUTF16;
136
David Benjamin3b94b0f2019-04-25 23:07:52137using testing::AnyOf;
138
initial.commit586acc5fe2008-07-26 22:42:52139//-----------------------------------------------------------------------------
140
ttuttle859dc7a2015-04-23 19:42:29141namespace net {
142
[email protected]13c8a092010-07-29 06:15:44143namespace {
144
[email protected]42cba2fb2013-03-29 19:58:57145const base::string16 kBar(ASCIIToUTF16("bar"));
146const base::string16 kBar2(ASCIIToUTF16("bar2"));
147const base::string16 kBar3(ASCIIToUTF16("bar3"));
148const base::string16 kBaz(ASCIIToUTF16("baz"));
149const base::string16 kFirst(ASCIIToUTF16("first"));
150const base::string16 kFoo(ASCIIToUTF16("foo"));
151const base::string16 kFoo2(ASCIIToUTF16("foo2"));
152const base::string16 kFoo3(ASCIIToUTF16("foo3"));
153const base::string16 kFou(ASCIIToUTF16("fou"));
154const base::string16 kSecond(ASCIIToUTF16("second"));
[email protected]42cba2fb2013-03-29 19:58:57155const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
[email protected]13c8a092010-07-29 06:15:44156
bnc2df4b522016-07-08 18:17:43157const char kAlternativeServiceHttpHeader[] =
158 "Alt-Svc: h2=\"mail.example.org:443\"\r\n";
159
ttuttle859dc7a2015-04-23 19:42:29160int GetIdleSocketCountInTransportSocketPool(HttpNetworkSession* session) {
Matt Menked23ab952019-03-06 00:24:40161 return session
162 ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
163 ProxyServer::Direct())
ttuttle859dc7a2015-04-23 19:42:29164 ->IdleSocketCount();
[email protected]e5c026642012-03-17 00:14:02165}
166
ttuttle859dc7a2015-04-23 19:42:29167bool IsTransportSocketPoolStalled(HttpNetworkSession* session) {
Matt Menked23ab952019-03-06 00:24:40168 return session
169 ->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
170 ProxyServer::Direct())
ttuttle859dc7a2015-04-23 19:42:29171 ->IsStalled();
[email protected]043b68c82013-08-22 23:41:52172}
173
[email protected]f3da152d2012-06-02 01:00:57174// Takes in a Value created from a NetLogHttpResponseParameter, and returns
175// a JSONified list of headers as a single string. Uses single quotes instead
176// of double quotes for easier comparison. Returns false on failure.
[email protected]ea5ef4c2013-06-13 22:50:27177bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
[email protected]f3da152d2012-06-02 01:00:57178 if (!params)
179 return false;
[email protected]ea5ef4c2013-06-13 22:50:27180 base::ListValue* header_list;
[email protected]f3da152d2012-06-02 01:00:57181 if (!params->GetList("headers", &header_list))
182 return false;
183 std::string double_quote_headers;
estade8d046462015-05-16 01:02:34184 base::JSONWriter::Write(*header_list, &double_quote_headers);
[email protected]466c9862013-12-03 22:05:28185 base::ReplaceChars(double_quote_headers, "\"", "'", headers);
[email protected]f3da152d2012-06-02 01:00:57186 return true;
187}
188
[email protected]029c83b62013-01-24 05:28:20189// Tests LoadTimingInfo in the case a socket is reused and no PAC script is
190// used.
ttuttle859dc7a2015-04-23 19:42:29191void TestLoadTimingReused(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20192 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19193 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]58e32bb2013-01-21 18:23:25194
[email protected]029c83b62013-01-24 05:28:20195 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
196 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
197
ttuttle859dc7a2015-04-23 19:42:29198 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20199 EXPECT_FALSE(load_timing_info.send_start.is_null());
[email protected]58e32bb2013-01-21 18:23:25200
201 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]58e32bb2013-01-21 18:23:25202
[email protected]3b23a222013-05-15 21:33:25203 // Set at a higher level.
[email protected]58e32bb2013-01-21 18:23:25204 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
205 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25206 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25207}
208
[email protected]029c83b62013-01-24 05:28:20209// Tests LoadTimingInfo in the case a new socket is used and no PAC script is
210// used.
ttuttle859dc7a2015-04-23 19:42:29211void TestLoadTimingNotReused(const LoadTimingInfo& load_timing_info,
[email protected]58e32bb2013-01-21 18:23:25212 int connect_timing_flags) {
[email protected]029c83b62013-01-24 05:28:20213 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19214 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20215
216 EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
217 EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
218
ttuttle859dc7a2015-04-23 19:42:29219 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
220 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20221 EXPECT_LE(load_timing_info.connect_timing.connect_end,
222 load_timing_info.send_start);
223
224 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20225
[email protected]3b23a222013-05-15 21:33:25226 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20227 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
228 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25229 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20230}
231
232// Tests LoadTimingInfo in the case a socket is reused and a PAC script is
233// used.
ttuttle859dc7a2015-04-23 19:42:29234void TestLoadTimingReusedWithPac(const LoadTimingInfo& load_timing_info) {
[email protected]029c83b62013-01-24 05:28:20235 EXPECT_TRUE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19236 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20237
ttuttle859dc7a2015-04-23 19:42:29238 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
[email protected]029c83b62013-01-24 05:28:20239
240 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
241 EXPECT_LE(load_timing_info.proxy_resolve_start,
242 load_timing_info.proxy_resolve_end);
243 EXPECT_LE(load_timing_info.proxy_resolve_end,
244 load_timing_info.send_start);
245 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20246
[email protected]3b23a222013-05-15 21:33:25247 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20248 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
249 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25250 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]029c83b62013-01-24 05:28:20251}
252
253// Tests LoadTimingInfo in the case a new socket is used and a PAC script is
254// used.
ttuttle859dc7a2015-04-23 19:42:29255void TestLoadTimingNotReusedWithPac(const LoadTimingInfo& load_timing_info,
[email protected]029c83b62013-01-24 05:28:20256 int connect_timing_flags) {
257 EXPECT_FALSE(load_timing_info.socket_reused);
mikecironef22f9812016-10-04 03:40:19258 EXPECT_NE(NetLogSource::kInvalidId, load_timing_info.socket_log_id);
[email protected]029c83b62013-01-24 05:28:20259
260 EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
261 EXPECT_LE(load_timing_info.proxy_resolve_start,
262 load_timing_info.proxy_resolve_end);
263 EXPECT_LE(load_timing_info.proxy_resolve_end,
264 load_timing_info.connect_timing.connect_start);
ttuttle859dc7a2015-04-23 19:42:29265 ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
266 connect_timing_flags);
[email protected]029c83b62013-01-24 05:28:20267 EXPECT_LE(load_timing_info.connect_timing.connect_end,
268 load_timing_info.send_start);
269
270 EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
[email protected]029c83b62013-01-24 05:28:20271
[email protected]3b23a222013-05-15 21:33:25272 // Set at a higher level.
[email protected]029c83b62013-01-24 05:28:20273 EXPECT_TRUE(load_timing_info.request_start_time.is_null());
274 EXPECT_TRUE(load_timing_info.request_start.is_null());
[email protected]3b23a222013-05-15 21:33:25275 EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
[email protected]58e32bb2013-01-21 18:23:25276}
277
Matt Menke2436b2f2018-12-11 18:07:11278// ProxyResolver that records URLs passed to it, and that can be told what
279// result to return.
280class CapturingProxyResolver : public ProxyResolver {
281 public:
282 CapturingProxyResolver()
283 : proxy_server_(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 80)) {}
284 ~CapturingProxyResolver() override = default;
285
286 int GetProxyForURL(const GURL& url,
287 ProxyInfo* results,
288 CompletionOnceCallback callback,
289 std::unique_ptr<Request>* request,
290 const NetLogWithSource& net_log) override {
291 results->UseProxyServer(proxy_server_);
292 resolved_.push_back(url);
293 return OK;
294 }
295
296 // Sets whether the resolver should use direct connections, instead of a
297 // proxy.
298 void set_proxy_server(ProxyServer proxy_server) {
299 proxy_server_ = proxy_server;
300 }
301
302 const std::vector<GURL>& resolved() const { return resolved_; }
303
304 private:
305 std::vector<GURL> resolved_;
306
307 ProxyServer proxy_server_;
308
309 DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
310};
311
312class CapturingProxyResolverFactory : public ProxyResolverFactory {
313 public:
314 explicit CapturingProxyResolverFactory(CapturingProxyResolver* resolver)
315 : ProxyResolverFactory(false), resolver_(resolver) {}
316
317 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
318 std::unique_ptr<ProxyResolver>* resolver,
319 CompletionOnceCallback callback,
320 std::unique_ptr<Request>* request) override {
321 *resolver = std::make_unique<ForwardingProxyResolver>(resolver_);
322 return OK;
323 }
324
325 private:
326 ProxyResolver* resolver_;
327};
328
danakj1fd259a02016-04-16 03:17:09329std::unique_ptr<HttpNetworkSession> CreateSession(
mmenkee65e7af2015-10-13 17:16:42330 SpdySessionDependencies* session_deps) {
[email protected]c6bf8152012-12-02 07:43:34331 return SpdySessionDependencies::SpdyCreateSession(session_deps);
[email protected]e8d536192008-10-17 22:21:14332}
333
xunjieli96f2a402017-06-05 17:24:27334class FailingProxyResolverFactory : public ProxyResolverFactory {
335 public:
336 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
337
338 // ProxyResolverFactory override.
Lily Houghton99597862018-03-07 16:40:42339 int CreateProxyResolver(const scoped_refptr<PacFileData>& script_data,
340 std::unique_ptr<ProxyResolver>* result,
Bence Békycc5b88a2018-05-25 20:24:17341 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:42342 std::unique_ptr<Request>* request) override {
xunjieli96f2a402017-06-05 17:24:27343 return ERR_PAC_SCRIPT_FAILED;
344 }
345};
346
David Benjamin5cb91132018-04-06 05:54:49347class TestSSLConfigService : public SSLConfigService {
348 public:
349 explicit TestSSLConfigService(const SSLConfig& config) : config_(config) {}
Ryan Sleevib8449e02018-07-15 04:31:07350 ~TestSSLConfigService() override = default;
David Benjamin5cb91132018-04-06 05:54:49351
352 void GetSSLConfig(SSLConfig* config) override { *config = config_; }
353
Nick Harper89bc7212018-07-31 19:07:57354 bool CanShareConnectionWithClientCerts(
355 const std::string& hostname) const override {
356 return false;
357 }
358
David Benjamin5cb91132018-04-06 05:54:49359 private:
David Benjamin5cb91132018-04-06 05:54:49360 SSLConfig config_;
361};
362
[email protected]448d4ca52012-03-04 04:12:23363} // namespace
364
Bence Béky98447b12018-05-08 03:14:01365class HttpNetworkTransactionTest : public PlatformTest,
366 public WithScopedTaskEnvironment {
[email protected]483fa202013-05-14 01:07:03367 public:
bncd16676a2016-07-20 16:23:01368 ~HttpNetworkTransactionTest() override {
[email protected]483fa202013-05-14 01:07:03369 // Important to restore the per-pool limit first, since the pool limit must
370 // always be greater than group limit, and the tests reduce both limits.
371 ClientSocketPoolManager::set_max_sockets_per_pool(
372 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
373 ClientSocketPoolManager::set_max_sockets_per_group(
374 HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
375 }
376
[email protected]e3ceb682011-06-28 23:55:46377 protected:
[email protected]23e482282013-06-14 16:08:02378 HttpNetworkTransactionTest()
Andrew Comminos517a92c2019-01-14 17:49:56379 : WithScopedTaskEnvironment(
380 base::test::ScopedTaskEnvironment::MainThreadType::IO_MOCK_TIME,
381 base::test::ScopedTaskEnvironment::NowSource::
382 MAIN_THREAD_MOCK_TIME),
Matt Menked6fd2a52019-03-20 06:14:36383 dummy_connect_job_params_(
384 nullptr /* client_socket_factory */,
385 nullptr /* host_resolver */,
Matt Menkeb88837e2019-03-20 11:50:40386 nullptr /* http_auth_cache */,
387 nullptr /* http_auth_handler_factory */,
388 nullptr /* spdy_session_pool */,
Matt Menkeb5fb42b2019-03-22 17:26:13389 nullptr /* quic_supported_versions */,
Matt Menkeb88837e2019-03-20 11:50:40390 nullptr /* quic_stream_factory */,
Matt Menked6fd2a52019-03-20 06:14:36391 nullptr /* proxy_delegate */,
392 nullptr /* http_user_agent_settings */,
393 SSLClientSocketContext(),
394 SSLClientSocketContext(),
395 nullptr /* socket_performance_watcher_factory */,
396 nullptr /* network_quality_estimator */,
397 nullptr /* net_log */,
398 nullptr /* websocket_endpoint_lock_manager */),
Andrew Comminos517a92c2019-01-14 17:49:56399 ssl_(ASYNC, OK),
bnc032658ba2016-09-26 18:17:15400 old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
[email protected]483fa202013-05-14 01:07:03401 HttpNetworkSession::NORMAL_SOCKET_POOL)),
402 old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
403 HttpNetworkSession::NORMAL_SOCKET_POOL)) {
bnca86731e2017-04-17 12:31:28404 session_deps_.enable_http2_alternative_service = true;
[email protected]483fa202013-05-14 01:07:03405 }
[email protected]bb88e1d32013-05-03 23:11:07406
[email protected]e3ceb682011-06-28 23:55:46407 struct SimpleGetHelperResult {
408 int rv;
409 std::string status_line;
410 std::string response_data;
sclittlefb249892015-09-10 21:33:22411 int64_t total_received_bytes;
412 int64_t total_sent_bytes;
[email protected]58e32bb2013-01-21 18:23:25413 LoadTimingInfo load_timing_info;
ttuttle1f2d7e92015-04-28 16:17:47414 ConnectionAttempts connection_attempts;
ttuttled9dbc652015-09-29 20:00:59415 IPEndPoint remote_endpoint_after_start;
[email protected]e3ceb682011-06-28 23:55:46416 };
417
dcheng67be2b1f2014-10-27 21:47:29418 void SetUp() override {
[email protected]0b0bf032010-09-21 18:08:50419 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55420 base::RunLoop().RunUntilIdle();
Andrew Comminos517a92c2019-01-14 17:49:56421 // Set an initial delay to ensure that the first call to TimeTicks::Now()
422 // before incrementing the counter does not return a null value.
423 FastForwardBy(TimeDelta::FromSeconds(1));
[email protected]2ff8b312010-04-26 22:20:54424 }
425
dcheng67be2b1f2014-10-27 21:47:29426 void TearDown() override {
[email protected]0b0bf032010-09-21 18:08:50427 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55428 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09429 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:55430 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09431 PlatformTest::TearDown();
[email protected]0b0bf032010-09-21 18:08:50432 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
fdoray92e35a72016-06-10 15:54:55433 base::RunLoop().RunUntilIdle();
[email protected]0e75a732008-10-16 20:36:09434 }
435
Andrew Comminos1f2ff1cc2018-12-14 05:22:38436 void Check100ResponseTiming(bool use_spdy);
437
[email protected]202965992011-12-07 23:04:51438 // Either |write_failure| specifies a write failure or |read_failure|
439 // specifies a read failure when using a reused socket. In either case, the
440 // failure should cause the network transaction to resend the request, and the
441 // other argument should be NULL.
442 void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
443 const MockRead* read_failure);
initial.commit586acc5fe2008-07-26 22:42:52444
[email protected]a34f61ee2014-03-18 20:59:49445 // Either |write_failure| specifies a write failure or |read_failure|
446 // specifies a read failure when using a reused socket. In either case, the
447 // failure should cause the network transaction to resend the request, and the
448 // other argument should be NULL.
449 void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:10450 const MockRead* read_failure,
451 bool use_spdy);
[email protected]a34f61ee2014-03-18 20:59:49452
Ryan Sleevib8d7ea02018-05-07 20:01:01453 SimpleGetHelperResult SimpleGetHelperForData(
454 base::span<StaticSocketDataProvider*> providers) {
[email protected]ff007e162009-05-23 09:13:15455 SimpleGetHelperResult out;
initial.commit586acc5fe2008-07-26 22:42:52456
[email protected]ff007e162009-05-23 09:13:15457 HttpRequestInfo request;
458 request.method = "GET";
bncce36dca22015-04-21 22:11:23459 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:10460 request.traffic_annotation =
461 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:52462
vishal.b62985ca92015-04-17 08:45:51463 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:07464 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:09465 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16466 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:27467
Ryan Sleevib8d7ea02018-05-07 20:01:01468 for (auto* provider : providers) {
469 session_deps_.socket_factory->AddSocketDataProvider(provider);
[email protected]5a60c8b2011-10-19 20:14:29470 }
initial.commit586acc5fe2008-07-26 22:42:52471
[email protected]49639fa2011-12-20 23:22:41472 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:52473
eroman24bc6a12015-05-06 19:55:48474 EXPECT_TRUE(log.bound().IsCapturing());
bnc691fda62016-08-12 00:43:16475 int rv = trans.Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:01476 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:52477
[email protected]ff007e162009-05-23 09:13:15478 out.rv = callback.WaitForResult();
bnc691fda62016-08-12 00:43:16479 out.total_received_bytes = trans.GetTotalReceivedBytes();
480 out.total_sent_bytes = trans.GetTotalSentBytes();
[email protected]58e32bb2013-01-21 18:23:25481
482 // Even in the failure cases that use this function, connections are always
483 // successfully established before the error.
bnc691fda62016-08-12 00:43:16484 EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info));
[email protected]58e32bb2013-01-21 18:23:25485 TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
486
[email protected]ff007e162009-05-23 09:13:15487 if (out.rv != OK)
488 return out;
489
bnc691fda62016-08-12 00:43:16490 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]fe2255a2011-09-20 19:37:50491 // Can't use ASSERT_* inside helper functions like this, so
492 // return an error.
wezca1070932016-05-26 20:30:52493 if (!response || !response->headers) {
[email protected]fe2255a2011-09-20 19:37:50494 out.rv = ERR_UNEXPECTED;
495 return out;
496 }
[email protected]ff007e162009-05-23 09:13:15497 out.status_line = response->headers->GetStatusLine();
498
Tsuyoshi Horo01faed62019-02-20 22:11:37499 EXPECT_EQ("127.0.0.1", response->remote_endpoint.ToStringWithoutPort());
500 EXPECT_EQ(80, response->remote_endpoint.port());
[email protected]6d81b482011-02-22 19:47:19501
ttuttled9dbc652015-09-29 20:00:59502 bool got_endpoint =
bnc691fda62016-08-12 00:43:16503 trans.GetRemoteEndpoint(&out.remote_endpoint_after_start);
ttuttled9dbc652015-09-29 20:00:59504 EXPECT_EQ(got_endpoint,
505 out.remote_endpoint_after_start.address().size() > 0);
506
bnc691fda62016-08-12 00:43:16507 rv = ReadTransaction(&trans, &out.response_data);
robpercival214763f2016-07-01 23:27:01508 EXPECT_THAT(rv, IsOk());
[email protected]b2fcd0e2010-12-01 15:19:40509
mmenke43758e62015-05-04 21:09:46510 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:40511 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:39512 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00513 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
514 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:39515 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:00516 entries, pos, NetLogEventType::HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
517 NetLogEventPhase::NONE);
[email protected]ff007e162009-05-23 09:13:15518
[email protected]f3da152d2012-06-02 01:00:57519 std::string line;
520 EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
521 EXPECT_EQ("GET / HTTP/1.1\r\n", line);
522
[email protected]79e1fd62013-06-20 06:50:04523 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:16524 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:04525 std::string value;
526 EXPECT_TRUE(request_headers.GetHeader("Host", &value));
bncce36dca22015-04-21 22:11:23527 EXPECT_EQ("www.example.org", value);
[email protected]79e1fd62013-06-20 06:50:04528 EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
529 EXPECT_EQ("keep-alive", value);
530
531 std::string response_headers;
532 EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
bncce36dca22015-04-21 22:11:23533 EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']",
[email protected]79e1fd62013-06-20 06:50:04534 response_headers);
[email protected]3deb9a52010-11-11 00:24:40535
bnc691fda62016-08-12 00:43:16536 out.total_received_bytes = trans.GetTotalReceivedBytes();
sclittlefb249892015-09-10 21:33:22537 // The total number of sent bytes should not have changed.
bnc691fda62016-08-12 00:43:16538 EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes());
sclittlefb249892015-09-10 21:33:22539
bnc691fda62016-08-12 00:43:16540 trans.GetConnectionAttempts(&out.connection_attempts);
[email protected]aecfbf22008-10-16 02:02:47541 return out;
[email protected]ff007e162009-05-23 09:13:15542 }
initial.commit586acc5fe2008-07-26 22:42:52543
Ryan Sleevib8d7ea02018-05-07 20:01:01544 SimpleGetHelperResult SimpleGetHelper(base::span<const MockRead> data_reads) {
sclittlefb249892015-09-10 21:33:22545 MockWrite data_writes[] = {
546 MockWrite("GET / HTTP/1.1\r\n"
547 "Host: www.example.org\r\n"
548 "Connection: keep-alive\r\n\r\n"),
549 };
[email protected]5a60c8b2011-10-19 20:14:29550
Ryan Sleevib8d7ea02018-05-07 20:01:01551 StaticSocketDataProvider reads(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:22552 StaticSocketDataProvider* data[] = {&reads};
Ryan Sleevib8d7ea02018-05-07 20:01:01553 SimpleGetHelperResult out = SimpleGetHelperForData(data);
sclittlefb249892015-09-10 21:33:22554
Ryan Sleevib8d7ea02018-05-07 20:01:01555 EXPECT_EQ(CountWriteBytes(data_writes), out.total_sent_bytes);
sclittlefb249892015-09-10 21:33:22556 return out;
[email protected]b8015c42013-12-24 15:18:19557 }
558
bnc032658ba2016-09-26 18:17:15559 void AddSSLSocketData() {
560 ssl_.next_proto = kProtoHTTP2;
Ryan Sleevi4f832092017-11-21 23:25:49561 ssl_.ssl_info.cert =
562 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem");
563 ASSERT_TRUE(ssl_.ssl_info.cert);
bnc032658ba2016-09-26 18:17:15564 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_);
565 }
566
[email protected]ff007e162009-05-23 09:13:15567 void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
568 int expected_status);
initial.commit586acc5fe2008-07-26 22:42:52569
[email protected]ff007e162009-05-23 09:13:15570 void ConnectStatusHelper(const MockRead& status);
[email protected]bb88e1d32013-05-03 23:11:07571
[email protected]bb88e1d32013-05-03 23:11:07572 void CheckErrorIsPassedBack(int error, IoMode mode);
573
Matt Menked6fd2a52019-03-20 06:14:36574 const CommonConnectJobParams dummy_connect_job_params_;
575
Douglas Creager134b52e2018-11-09 18:00:14576 // These clocks are defined here, even though they're only used in the
577 // Reporting tests below, since they need to be destroyed after
578 // |session_deps_|.
579 base::SimpleTestClock clock_;
580 base::SimpleTestTickClock tick_clock_;
581
[email protected]4bd46222013-05-14 19:32:23582 SpdyTestUtil spdy_util_;
[email protected]bb88e1d32013-05-03 23:11:07583 SpdySessionDependencies session_deps_;
bnc032658ba2016-09-26 18:17:15584 SSLSocketDataProvider ssl_;
[email protected]483fa202013-05-14 01:07:03585
586 // Original socket limits. Some tests set these. Safest to always restore
587 // them once each test has been run.
588 int old_max_group_sockets_;
589 int old_max_pool_sockets_;
[email protected]ff007e162009-05-23 09:13:15590};
[email protected]231d5a32008-09-13 00:45:27591
[email protected]448d4ca52012-03-04 04:12:23592namespace {
593
ryansturm49a8cb12016-06-15 16:51:09594class BeforeHeadersSentHandler {
[email protected]597a1ab2014-06-26 08:12:27595 public:
ryansturm49a8cb12016-06-15 16:51:09596 BeforeHeadersSentHandler()
597 : observed_before_headers_sent_with_proxy_(false),
598 observed_before_headers_sent_(false) {}
[email protected]597a1ab2014-06-26 08:12:27599
ryansturm49a8cb12016-06-15 16:51:09600 void OnBeforeHeadersSent(const ProxyInfo& proxy_info,
601 HttpRequestHeaders* request_headers) {
602 observed_before_headers_sent_ = true;
603 if (!proxy_info.is_http() && !proxy_info.is_https() &&
604 !proxy_info.is_quic()) {
605 return;
606 }
607 observed_before_headers_sent_with_proxy_ = true;
[email protected]597a1ab2014-06-26 08:12:27608 observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
609 }
610
ryansturm49a8cb12016-06-15 16:51:09611 bool observed_before_headers_sent_with_proxy() const {
612 return observed_before_headers_sent_with_proxy_;
613 }
614
615 bool observed_before_headers_sent() const {
616 return observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27617 }
618
619 std::string observed_proxy_server_uri() const {
620 return observed_proxy_server_uri_;
621 }
622
623 private:
ryansturm49a8cb12016-06-15 16:51:09624 bool observed_before_headers_sent_with_proxy_;
625 bool observed_before_headers_sent_;
[email protected]597a1ab2014-06-26 08:12:27626 std::string observed_proxy_server_uri_;
627
ryansturm49a8cb12016-06-15 16:51:09628 DISALLOW_COPY_AND_ASSIGN(BeforeHeadersSentHandler);
[email protected]597a1ab2014-06-26 08:12:27629};
630
[email protected]15a5ccf82008-10-23 19:57:43631// Fill |str| with a long header list that consumes >= |size| bytes.
632void FillLargeHeadersString(std::string* str, int size) {
thestig9d3bb0c2015-01-24 00:49:51633 const char row[] =
[email protected]4ddaf2502008-10-23 18:26:19634 "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
635 const int sizeof_row = strlen(row);
636 const int num_rows = static_cast<int>(
637 ceil(static_cast<float>(size) / sizeof_row));
638 const int sizeof_data = num_rows * sizeof_row;
639 DCHECK(sizeof_data >= size);
[email protected]15a5ccf82008-10-23 19:57:43640 str->reserve(sizeof_data);
[email protected]372d34a2008-11-05 21:30:51641
[email protected]4ddaf2502008-10-23 18:26:19642 for (int i = 0; i < num_rows; ++i)
[email protected]15a5ccf82008-10-23 19:57:43643 str->append(row, sizeof_row);
[email protected]4ddaf2502008-10-23 18:26:19644}
645
thakis84dff942015-07-28 20:47:38646#if defined(NTLM_PORTABLE)
Zentaro Kavanagh6ccee512017-09-28 18:34:09647uint64_t MockGetMSTime() {
648 // Tue, 23 May 2017 20:13:07 +0000
649 return 131400439870000000;
650}
651
[email protected]385a4672009-03-11 22:21:29652// Alternative functions that eliminate randomness and dependency on the local
653// host name so that the generated NTLM messages are reproducible.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37654void MockGenerateRandom(uint8_t* output, size_t n) {
655 // This is set to 0xaa because the client challenge for testing in
656 // [MS-NLMP] Section 4.2.1 is 8 bytes of 0xaa.
657 memset(output, 0xaa, n);
[email protected]385a4672009-03-11 22:21:29658}
659
[email protected]fe2bc6a2009-03-23 16:52:20660std::string MockGetHostName() {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:37661 return ntlm::test::kHostnameAscii;
[email protected]385a4672009-03-11 22:21:29662}
thakis84dff942015-07-28 20:47:38663#endif // defined(NTLM_PORTABLE)
[email protected]385a4672009-03-11 22:21:29664
Matt Menked6fd2a52019-03-20 06:14:36665class CaptureGroupIdTransportSocketPool : public TransportClientSocketPool {
[email protected]04e5be32009-06-26 20:00:31666 public:
Matt Menked6fd2a52019-03-20 06:14:36667 explicit CaptureGroupIdTransportSocketPool(
668 const CommonConnectJobParams* common_connect_job_params)
669 : TransportClientSocketPool(0,
670 0,
671 base::TimeDelta(),
Matt Menkeaafff542019-04-22 22:09:36672 ProxyServer::Direct(),
673 false /* is_for_websockets */,
Matt Menked6fd2a52019-03-20 06:14:36674 common_connect_job_params,
675 nullptr /* ssl_config_service */) {}
[email protected]e60e47a2010-07-14 03:37:18676
Matt Menkef6edce752019-03-19 17:21:56677 const ClientSocketPool::GroupId& last_group_id_received() const {
678 return last_group_id_;
[email protected]d80a4322009-08-14 07:07:49679 }
680
Tarun Bansal162eabe52018-01-20 01:16:39681 bool socket_requested() const { return socket_requested_; }
682
Matt Menke28ac03e2019-02-25 22:25:50683 int RequestSocket(
Matt Menkef6edce752019-03-19 17:21:56684 const ClientSocketPool::GroupId& group_id,
Matt Menkebd12b7e2019-03-25 21:12:03685 scoped_refptr<ClientSocketPool::SocketParams> socket_params,
Matt Menkef09e64c2019-04-23 22:16:28686 const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
Matt Menke28ac03e2019-02-25 22:25:50687 RequestPriority priority,
688 const SocketTag& socket_tag,
689 ClientSocketPool::RespectLimits respect_limits,
690 ClientSocketHandle* handle,
691 CompletionOnceCallback callback,
692 const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback,
693 const NetLogWithSource& net_log) override {
Matt Menkef6edce752019-03-19 17:21:56694 last_group_id_ = group_id;
Tarun Bansal162eabe52018-01-20 01:16:39695 socket_requested_ = true;
[email protected]04e5be32009-06-26 20:00:31696 return ERR_IO_PENDING;
697 }
Matt Menkef6edce752019-03-19 17:21:56698 void CancelRequest(const ClientSocketPool::GroupId& group_id,
Matt Menke7eb405e2019-04-25 20:48:21699 ClientSocketHandle* handle,
700 bool cancel_connect_job) override {}
Matt Menkef6edce752019-03-19 17:21:56701 void ReleaseSocket(const ClientSocketPool::GroupId& group_id,
danakj1fd259a02016-04-16 03:17:09702 std::unique_ptr<StreamSocket> socket,
Matt Menkebf3c767d2019-04-15 23:28:24703 int64_t generation) override {}
dmichaeld6e570d2014-12-18 22:30:57704 void CloseIdleSockets() override {}
Matt Menkef6edce752019-03-19 17:21:56705 void CloseIdleSocketsInGroup(
706 const ClientSocketPool::GroupId& group_id) override {}
dmichaeld6e570d2014-12-18 22:30:57707 int IdleSocketCount() const override { return 0; }
Matt Menkef6edce752019-03-19 17:21:56708 size_t IdleSocketCountInGroup(
709 const ClientSocketPool::GroupId& group_id) const override {
[email protected]04e5be32009-06-26 20:00:31710 return 0;
711 }
Matt Menkef6edce752019-03-19 17:21:56712 LoadState GetLoadState(const ClientSocketPool::GroupId& group_id,
dmichaeld6e570d2014-12-18 22:30:57713 const ClientSocketHandle* handle) const override {
[email protected]04e5be32009-06-26 20:00:31714 return LOAD_STATE_IDLE;
715 }
[email protected]d80a4322009-08-14 07:07:49716
717 private:
Matt Menkef6edce752019-03-19 17:21:56718 ClientSocketPool::GroupId last_group_id_;
Tarun Bansal162eabe52018-01-20 01:16:39719 bool socket_requested_ = false;
[email protected]04e5be32009-06-26 20:00:31720};
721
[email protected]231d5a32008-09-13 00:45:27722//-----------------------------------------------------------------------------
723
[email protected]79cb5c12011-09-12 13:12:04724// Helper functions for validating that AuthChallengeInfo's are correctly
725// configured for common cases.
Emily Starkf2c9bbd2019-04-09 17:08:58726bool CheckBasicServerAuth(
727 const base::Optional<AuthChallengeInfo>& auth_challenge) {
[email protected]79cb5c12011-09-12 13:12:04728 if (!auth_challenge)
729 return false;
730 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43731 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04732 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19733 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04734 return true;
735}
736
Emily Starkf2c9bbd2019-04-09 17:08:58737bool CheckBasicProxyAuth(
738 const base::Optional<AuthChallengeInfo>& auth_challenge) {
[email protected]79cb5c12011-09-12 13:12:04739 if (!auth_challenge)
740 return false;
741 EXPECT_TRUE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43742 EXPECT_EQ("http://myproxy:70", auth_challenge->challenger.Serialize());
743 EXPECT_EQ("MyRealm1", auth_challenge->realm);
744 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
745 return true;
746}
747
Emily Starkf2c9bbd2019-04-09 17:08:58748bool CheckBasicSecureProxyAuth(
749 const base::Optional<AuthChallengeInfo>& auth_challenge) {
asanka098c0092016-06-16 20:18:43750 if (!auth_challenge)
751 return false;
752 EXPECT_TRUE(auth_challenge->is_proxy);
753 EXPECT_EQ("https://myproxy:70", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04754 EXPECT_EQ("MyRealm1", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19755 EXPECT_EQ(kBasicAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04756 return true;
757}
758
Emily Starkf2c9bbd2019-04-09 17:08:58759bool CheckDigestServerAuth(
760 const base::Optional<AuthChallengeInfo>& auth_challenge) {
[email protected]79cb5c12011-09-12 13:12:04761 if (!auth_challenge)
762 return false;
763 EXPECT_FALSE(auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:43764 EXPECT_EQ("http://www.example.org", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04765 EXPECT_EQ("digestive", auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19766 EXPECT_EQ(kDigestAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04767 return true;
768}
769
thakis84dff942015-07-28 20:47:38770#if defined(NTLM_PORTABLE)
Emily Starkf2c9bbd2019-04-09 17:08:58771bool CheckNTLMServerAuth(
772 const base::Optional<AuthChallengeInfo>& auth_challenge) {
[email protected]79cb5c12011-09-12 13:12:04773 if (!auth_challenge)
774 return false;
775 EXPECT_FALSE(auth_challenge->is_proxy);
Zentaro Kavanagh1890a3d2018-01-29 19:52:55776 EXPECT_EQ("https://server", auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:04777 EXPECT_EQ(std::string(), auth_challenge->realm);
aberentbba302d2015-12-03 10:20:19778 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
[email protected]79cb5c12011-09-12 13:12:04779 return true;
780}
David Benjamin5cb91132018-04-06 05:54:49781
Emily Starkf2c9bbd2019-04-09 17:08:58782bool CheckNTLMProxyAuth(
783 const base::Optional<AuthChallengeInfo>& auth_challenge) {
David Benjamin5cb91132018-04-06 05:54:49784 if (!auth_challenge)
785 return false;
786 EXPECT_TRUE(auth_challenge->is_proxy);
787 EXPECT_EQ("http://server", auth_challenge->challenger.Serialize());
788 EXPECT_EQ(std::string(), auth_challenge->realm);
789 EXPECT_EQ(kNtlmAuthScheme, auth_challenge->scheme);
790 return true;
791}
thakis84dff942015-07-28 20:47:38792#endif // defined(NTLM_PORTABLE)
[email protected]79cb5c12011-09-12 13:12:04793
[email protected]448d4ca52012-03-04 04:12:23794} // namespace
795
bncd16676a2016-07-20 16:23:01796TEST_F(HttpNetworkTransactionTest, Basic) {
danakj1fd259a02016-04-16 03:17:09797 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:16798 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]231d5a32008-09-13 00:45:27799}
800
bncd16676a2016-07-20 16:23:01801TEST_F(HttpNetworkTransactionTest, SimpleGET) {
[email protected]231d5a32008-09-13 00:45:27802 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35803 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
804 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06805 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27806 };
Ryan Sleevib8d7ea02018-05-07 20:01:01807 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01808 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27809 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
810 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01811 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22812 EXPECT_EQ(reads_size, out.total_received_bytes);
ttuttle1f2d7e92015-04-28 16:17:47813 EXPECT_EQ(0u, out.connection_attempts.size());
ttuttled9dbc652015-09-29 20:00:59814
815 EXPECT_FALSE(out.remote_endpoint_after_start.address().empty());
[email protected]231d5a32008-09-13 00:45:27816}
817
818// Response with no status line.
bncd16676a2016-07-20 16:23:01819TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
[email protected]231d5a32008-09-13 00:45:27820 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35821 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:06822 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27823 };
Ryan Sleevib8d7ea02018-05-07 20:01:01824 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41825 EXPECT_THAT(out.rv, IsOk());
826 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
827 EXPECT_EQ("hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01828 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41829 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27830}
831
mmenkea7da6da2016-09-01 21:56:52832// Response with no status line, and a weird port. Should fail by default.
833TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPort) {
834 MockRead data_reads[] = {
835 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
836 };
837
Ryan Sleevib8d7ea02018-05-07 20:01:01838 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52839 session_deps_.socket_factory->AddSocketDataProvider(&data);
840
841 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
842
krasinc06a72a2016-12-21 03:42:46843 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58844 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19845 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52846
mmenkea7da6da2016-09-01 21:56:52847 request.method = "GET";
848 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e62018-02-07 07:41:10849 request.traffic_annotation =
850 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
851
mmenkea7da6da2016-09-01 21:56:52852 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20853 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52854 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
855}
856
Shivani Sharmafdcaefd2017-11-02 00:12:26857// Tests that request info can be destroyed after the headers phase is complete.
858TEST_F(HttpNetworkTransactionTest, SimpleGETNoReadDestroyRequestInfo) {
859 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
860 auto trans =
861 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
862
863 MockRead data_reads[] = {
864 MockRead("HTTP/1.0 200 OK\r\n"), MockRead("Connection: keep-alive\r\n"),
865 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, 0),
866 };
Ryan Sleevib8d7ea02018-05-07 20:01:01867 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Shivani Sharmafdcaefd2017-11-02 00:12:26868 session_deps_.socket_factory->AddSocketDataProvider(&data);
869
870 TestCompletionCallback callback;
871
872 {
873 auto request = std::make_unique<HttpRequestInfo>();
874 request->method = "GET";
875 request->url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:10876 request->traffic_annotation =
877 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Shivani Sharmafdcaefd2017-11-02 00:12:26878
879 int rv =
880 trans->Start(request.get(), callback.callback(), NetLogWithSource());
881
882 EXPECT_THAT(callback.GetResult(rv), IsOk());
883 } // Let request info be destroyed.
884
885 trans.reset();
886}
887
mmenkea7da6da2016-09-01 21:56:52888// Response with no status line, and a weird port. Option to allow weird ports
889// enabled.
890TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeadersWeirdPortAllowed) {
891 MockRead data_reads[] = {
892 MockRead("hello world"), MockRead(SYNCHRONOUS, OK),
893 };
894
Ryan Sleevib8d7ea02018-05-07 20:01:01895 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
mmenkea7da6da2016-09-01 21:56:52896 session_deps_.socket_factory->AddSocketDataProvider(&data);
897 session_deps_.http_09_on_non_default_ports_enabled = true;
898 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
899
krasinc06a72a2016-12-21 03:42:46900 HttpRequestInfo request;
bnc87dcefc2017-05-25 12:47:58901 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:19902 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenkea7da6da2016-09-01 21:56:52903
mmenkea7da6da2016-09-01 21:56:52904 request.method = "GET";
905 request.url = GURL("http://www.example.com:2000/");
Ramin Halavatib5e433e62018-02-07 07:41:10906 request.traffic_annotation =
907 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
908
mmenkea7da6da2016-09-01 21:56:52909 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:20910 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea7da6da2016-09-01 21:56:52911 EXPECT_THAT(callback.GetResult(rv), IsOk());
912
913 const HttpResponseInfo* info = trans->GetResponseInfo();
914 ASSERT_TRUE(info->headers);
915 EXPECT_EQ("HTTP/0.9 200 OK", info->headers->GetStatusLine());
916
917 // Don't bother to read the body - that's verified elsewhere, important thing
918 // is that the option to allow HTTP/0.9 on non-default ports is respected.
919}
920
[email protected]231d5a32008-09-13 00:45:27921// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01922TEST_F(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
[email protected]231d5a32008-09-13 00:45:27923 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35924 MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06925 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27926 };
Ryan Sleevib8d7ea02018-05-07 20:01:01927 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01928 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27929 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
930 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01931 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22932 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27933}
934
935// Allow up to 4 bytes of junk to precede status line.
bncd16676a2016-07-20 16:23:01936TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
[email protected]231d5a32008-09-13 00:45:27937 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35938 MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06939 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27940 };
Ryan Sleevib8d7ea02018-05-07 20:01:01941 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01942 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27943 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
944 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01945 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22946 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27947}
948
949// Beyond 4 bytes of slop and it should fail to find a status line.
bncd16676a2016-07-20 16:23:01950TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
[email protected]231d5a32008-09-13 00:45:27951 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35952 MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
[email protected]8ddf8322012-02-23 18:08:06953 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27954 };
Ryan Sleevib8d7ea02018-05-07 20:01:01955 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41956 EXPECT_THAT(out.rv, IsOk());
957 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
958 EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01959 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41960 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27961}
962
963// Same as StatusLineJunk4Bytes, except the read chunks are smaller.
bncd16676a2016-07-20 16:23:01964TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
[email protected]231d5a32008-09-13 00:45:27965 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35966 MockRead("\n"),
967 MockRead("\n"),
968 MockRead("Q"),
969 MockRead("J"),
970 MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
[email protected]8ddf8322012-02-23 18:08:06971 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27972 };
Ryan Sleevib8d7ea02018-05-07 20:01:01973 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:01974 EXPECT_THAT(out.rv, IsOk());
[email protected]231d5a32008-09-13 00:45:27975 EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
976 EXPECT_EQ("DATA", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01977 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:22978 EXPECT_EQ(reads_size, out.total_received_bytes);
[email protected]231d5a32008-09-13 00:45:27979}
980
981// Close the connection before enough bytes to have a status line.
bncd16676a2016-07-20 16:23:01982TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
[email protected]231d5a32008-09-13 00:45:27983 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:35984 MockRead("HTT"),
[email protected]8ddf8322012-02-23 18:08:06985 MockRead(SYNCHRONOUS, OK),
[email protected]231d5a32008-09-13 00:45:27986 };
Ryan Sleevib8d7ea02018-05-07 20:01:01987 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41988 EXPECT_THAT(out.rv, IsOk());
989 EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
990 EXPECT_EQ("HTT", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:01991 int64_t reads_size = CountReadBytes(data_reads);
mmenkea2dcd3bf2016-08-16 21:49:41992 EXPECT_EQ(reads_size, out.total_received_bytes);
initial.commit586acc5fe2008-07-26 22:42:52993}
994
[email protected]f9d44aa2008-09-23 23:57:17995// Simulate a 204 response, lacking a Content-Length header, sent over a
996// persistent connection. The response should still terminate since a 204
997// cannot have a response body.
bncd16676a2016-07-20 16:23:01998TEST_F(HttpNetworkTransactionTest, StopsReading204) {
[email protected]b8015c42013-12-24 15:18:19999 char junk[] = "junk";
[email protected]f9d44aa2008-09-23 23:57:171000 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351001 MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
[email protected]b8015c42013-12-24 15:18:191002 MockRead(junk), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:061003 MockRead(SYNCHRONOUS, OK),
[email protected]f9d44aa2008-09-23 23:57:171004 };
Ryan Sleevib8d7ea02018-05-07 20:01:011005 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011006 EXPECT_THAT(out.rv, IsOk());
[email protected]f9d44aa2008-09-23 23:57:171007 EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
1008 EXPECT_EQ("", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:011009 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:221010 int64_t response_size = reads_size - strlen(junk);
1011 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]f9d44aa2008-09-23 23:57:171012}
1013
[email protected]0877e3d2009-10-17 22:29:571014// A simple request using chunked encoding with some extra data after.
bncd16676a2016-07-20 16:23:011015TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
[email protected]b8015c42013-12-24 15:18:191016 std::string final_chunk = "0\r\n\r\n";
1017 std::string extra_data = "HTTP/1.1 200 OK\r\n";
1018 std::string last_read = final_chunk + extra_data;
[email protected]0877e3d2009-10-17 22:29:571019 MockRead data_reads[] = {
1020 MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
1021 MockRead("5\r\nHello\r\n"),
1022 MockRead("1\r\n"),
1023 MockRead(" \r\n"),
1024 MockRead("5\r\nworld\r\n"),
[email protected]b8015c42013-12-24 15:18:191025 MockRead(last_read.data()),
[email protected]8ddf8322012-02-23 18:08:061026 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:571027 };
Ryan Sleevib8d7ea02018-05-07 20:01:011028 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011029 EXPECT_THAT(out.rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:571030 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1031 EXPECT_EQ("Hello world", out.response_data);
Ryan Sleevib8d7ea02018-05-07 20:01:011032 int64_t reads_size = CountReadBytes(data_reads);
sclittlefb249892015-09-10 21:33:221033 int64_t response_size = reads_size - extra_data.size();
1034 EXPECT_EQ(response_size, out.total_received_bytes);
[email protected]0877e3d2009-10-17 22:29:571035}
1036
[email protected]9fe44f52010-09-23 18:36:001037// Next tests deal with http://crbug.com/56344.
1038
bncd16676a2016-07-20 16:23:011039TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001040 MultipleContentLengthHeadersNoTransferEncoding) {
1041 MockRead data_reads[] = {
1042 MockRead("HTTP/1.1 200 OK\r\n"),
1043 MockRead("Content-Length: 10\r\n"),
1044 MockRead("Content-Length: 5\r\n\r\n"),
1045 };
Ryan Sleevib8d7ea02018-05-07 20:01:011046 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011047 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]9fe44f52010-09-23 18:36:001048}
1049
bncd16676a2016-07-20 16:23:011050TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041051 DuplicateContentLengthHeadersNoTransferEncoding) {
1052 MockRead data_reads[] = {
1053 MockRead("HTTP/1.1 200 OK\r\n"),
1054 MockRead("Content-Length: 5\r\n"),
1055 MockRead("Content-Length: 5\r\n\r\n"),
1056 MockRead("Hello"),
1057 };
Ryan Sleevib8d7ea02018-05-07 20:01:011058 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011059 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041060 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1061 EXPECT_EQ("Hello", out.response_data);
1062}
1063
bncd16676a2016-07-20 16:23:011064TEST_F(HttpNetworkTransactionTest,
[email protected]44b52042010-10-29 22:48:041065 ComplexContentLengthHeadersNoTransferEncoding) {
1066 // More than 2 dupes.
1067 {
1068 MockRead data_reads[] = {
1069 MockRead("HTTP/1.1 200 OK\r\n"),
1070 MockRead("Content-Length: 5\r\n"),
1071 MockRead("Content-Length: 5\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]44b52042010-10-29 22:48:041077 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1078 EXPECT_EQ("Hello", out.response_data);
1079 }
1080 // HTTP/1.0
1081 {
1082 MockRead data_reads[] = {
1083 MockRead("HTTP/1.0 200 OK\r\n"),
1084 MockRead("Content-Length: 5\r\n"),
1085 MockRead("Content-Length: 5\r\n"),
1086 MockRead("Content-Length: 5\r\n\r\n"),
1087 MockRead("Hello"),
1088 };
Ryan Sleevib8d7ea02018-05-07 20:01:011089 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011090 EXPECT_THAT(out.rv, IsOk());
[email protected]44b52042010-10-29 22:48:041091 EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
1092 EXPECT_EQ("Hello", out.response_data);
1093 }
1094 // 2 dupes and one mismatched.
1095 {
1096 MockRead data_reads[] = {
1097 MockRead("HTTP/1.1 200 OK\r\n"),
1098 MockRead("Content-Length: 10\r\n"),
1099 MockRead("Content-Length: 10\r\n"),
1100 MockRead("Content-Length: 5\r\n\r\n"),
1101 };
Ryan Sleevib8d7ea02018-05-07 20:01:011102 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011103 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH));
[email protected]44b52042010-10-29 22:48:041104 }
1105}
1106
bncd16676a2016-07-20 16:23:011107TEST_F(HttpNetworkTransactionTest,
[email protected]9fe44f52010-09-23 18:36:001108 MultipleContentLengthHeadersTransferEncoding) {
1109 MockRead data_reads[] = {
1110 MockRead("HTTP/1.1 200 OK\r\n"),
1111 MockRead("Content-Length: 666\r\n"),
1112 MockRead("Content-Length: 1337\r\n"),
1113 MockRead("Transfer-Encoding: chunked\r\n\r\n"),
1114 MockRead("5\r\nHello\r\n"),
1115 MockRead("1\r\n"),
1116 MockRead(" \r\n"),
1117 MockRead("5\r\nworld\r\n"),
1118 MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:061119 MockRead(SYNCHRONOUS, OK),
[email protected]9fe44f52010-09-23 18:36:001120 };
Ryan Sleevib8d7ea02018-05-07 20:01:011121 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011122 EXPECT_THAT(out.rv, IsOk());
[email protected]9fe44f52010-09-23 18:36:001123 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1124 EXPECT_EQ("Hello world", out.response_data);
1125}
1126
[email protected]1628fe92011-10-04 23:04:551127// Next tests deal with http://crbug.com/98895.
1128
1129// Checks that a single Content-Disposition header results in no error.
bncd16676a2016-07-20 16:23:011130TEST_F(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
[email protected]1628fe92011-10-04 23:04:551131 MockRead data_reads[] = {
1132 MockRead("HTTP/1.1 200 OK\r\n"),
1133 MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
1134 MockRead("Content-Length: 5\r\n\r\n"),
1135 MockRead("Hello"),
1136 };
Ryan Sleevib8d7ea02018-05-07 20:01:011137 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011138 EXPECT_THAT(out.rv, IsOk());
[email protected]1628fe92011-10-04 23:04:551139 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1140 EXPECT_EQ("Hello", out.response_data);
1141}
1142
[email protected]54a9c6e52012-03-21 20:10:591143// Checks that two identical Content-Disposition headers result in no error.
bncd16676a2016-07-20 16:23:011144TEST_F(HttpNetworkTransactionTest, TwoIdenticalContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551145 MockRead data_reads[] = {
1146 MockRead("HTTP/1.1 200 OK\r\n"),
1147 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1148 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1149 MockRead("Content-Length: 5\r\n\r\n"),
1150 MockRead("Hello"),
1151 };
Ryan Sleevib8d7ea02018-05-07 20:01:011152 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011153 EXPECT_THAT(out.rv, IsOk());
[email protected]54a9c6e52012-03-21 20:10:591154 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1155 EXPECT_EQ("Hello", out.response_data);
[email protected]1628fe92011-10-04 23:04:551156}
1157
1158// Checks that two distinct Content-Disposition headers result in an error.
bncd16676a2016-07-20 16:23:011159TEST_F(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
[email protected]1628fe92011-10-04 23:04:551160 MockRead data_reads[] = {
1161 MockRead("HTTP/1.1 200 OK\r\n"),
1162 MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
1163 MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
1164 MockRead("Content-Length: 5\r\n\r\n"),
1165 MockRead("Hello"),
1166 };
Ryan Sleevib8d7ea02018-05-07 20:01:011167 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011168 EXPECT_THAT(out.rv,
1169 IsError(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION));
[email protected]1628fe92011-10-04 23:04:551170}
1171
[email protected]54a9c6e52012-03-21 20:10:591172// Checks that two identical Location headers result in no error.
1173// Also tests Location header behavior.
bncd16676a2016-07-20 16:23:011174TEST_F(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551175 MockRead data_reads[] = {
1176 MockRead("HTTP/1.1 302 Redirect\r\n"),
1177 MockRead("Location: http://good.com/\r\n"),
[email protected]54a9c6e52012-03-21 20:10:591178 MockRead("Location: http://good.com/\r\n"),
[email protected]1628fe92011-10-04 23:04:551179 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061180 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551181 };
1182
1183 HttpRequestInfo request;
1184 request.method = "GET";
1185 request.url = GURL("http://redirect.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101186 request.traffic_annotation =
1187 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1628fe92011-10-04 23:04:551188
danakj1fd259a02016-04-16 03:17:091189 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161190 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1628fe92011-10-04 23:04:551191
Ryan Sleevib8d7ea02018-05-07 20:01:011192 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071193 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1628fe92011-10-04 23:04:551194
[email protected]49639fa2011-12-20 23:22:411195 TestCompletionCallback callback;
[email protected]1628fe92011-10-04 23:04:551196
tfarina42834112016-09-22 13:38:201197 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011198 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1628fe92011-10-04 23:04:551199
robpercival214763f2016-07-01 23:27:011200 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]1628fe92011-10-04 23:04:551201
bnc691fda62016-08-12 00:43:161202 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521203 ASSERT_TRUE(response);
1204 ASSERT_TRUE(response->headers);
[email protected]1628fe92011-10-04 23:04:551205 EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
1206 std::string url;
1207 EXPECT_TRUE(response->headers->IsRedirect(&url));
1208 EXPECT_EQ("http://good.com/", url);
tbansal2ecbbc72016-10-06 17:15:471209 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]1628fe92011-10-04 23:04:551210}
1211
[email protected]1628fe92011-10-04 23:04:551212// Checks that two distinct Location headers result in an error.
bncd16676a2016-07-20 16:23:011213TEST_F(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
[email protected]1628fe92011-10-04 23:04:551214 MockRead data_reads[] = {
1215 MockRead("HTTP/1.1 302 Redirect\r\n"),
1216 MockRead("Location: http://good.com/\r\n"),
1217 MockRead("Location: http://evil.com/\r\n"),
1218 MockRead("Content-Length: 0\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:061219 MockRead(SYNCHRONOUS, OK),
[email protected]1628fe92011-10-04 23:04:551220 };
Ryan Sleevib8d7ea02018-05-07 20:01:011221 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:011222 EXPECT_THAT(out.rv, IsError(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION));
[email protected]1628fe92011-10-04 23:04:551223}
1224
[email protected]ef0faf2e72009-03-05 23:27:231225// Do a request using the HEAD method. Verify that we don't try to read the
1226// message body (since HEAD has none).
bncd16676a2016-07-20 16:23:011227TEST_F(HttpNetworkTransactionTest, Head) {
[email protected]1c773ea12009-04-28 19:58:421228 HttpRequestInfo request;
[email protected]ef0faf2e72009-03-05 23:27:231229 request.method = "HEAD";
bncce36dca22015-04-21 22:11:231230 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101231 request.traffic_annotation =
1232 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ef0faf2e72009-03-05 23:27:231233
danakj1fd259a02016-04-16 03:17:091234 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161235 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:091236 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:161237 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:091238 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
1239 base::Unretained(&headers_handler)));
[email protected]cb9bf6ca2011-01-28 13:15:271240
[email protected]ef0faf2e72009-03-05 23:27:231241 MockWrite data_writes1[] = {
csharrisonf473dd192015-08-18 13:54:131242 MockWrite("HEAD / HTTP/1.1\r\n"
1243 "Host: www.example.org\r\n"
1244 "Connection: keep-alive\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231245 };
1246 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:231247 MockRead("HTTP/1.1 404 Not Found\r\n"), MockRead("Server: Blah\r\n"),
1248 MockRead("Content-Length: 1234\r\n\r\n"),
[email protected]ef0faf2e72009-03-05 23:27:231249
mmenked39192ee2015-12-09 00:57:231250 // No response body because the test stops reading here.
1251 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]ef0faf2e72009-03-05 23:27:231252 };
1253
Ryan Sleevib8d7ea02018-05-07 20:01:011254 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:071255 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]ef0faf2e72009-03-05 23:27:231256
[email protected]49639fa2011-12-20 23:22:411257 TestCompletionCallback callback1;
[email protected]ef0faf2e72009-03-05 23:27:231258
tfarina42834112016-09-22 13:38:201259 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011260 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ef0faf2e72009-03-05 23:27:231261
1262 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:011263 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231264
bnc691fda62016-08-12 00:43:161265 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521266 ASSERT_TRUE(response);
[email protected]ef0faf2e72009-03-05 23:27:231267
1268 // Check that the headers got parsed.
wezca1070932016-05-26 20:30:521269 EXPECT_TRUE(response->headers);
[email protected]ef0faf2e72009-03-05 23:27:231270 EXPECT_EQ(1234, response->headers->GetContentLength());
1271 EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471272 EXPECT_TRUE(response->proxy_server.is_direct());
ryansturm49a8cb12016-06-15 16:51:091273 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
1274 EXPECT_FALSE(headers_handler.observed_before_headers_sent_with_proxy());
[email protected]ef0faf2e72009-03-05 23:27:231275
1276 std::string server_header;
olli.raulaee489a52016-01-25 08:37:101277 size_t iter = 0;
[email protected]ef0faf2e72009-03-05 23:27:231278 bool has_server_header = response->headers->EnumerateHeader(
1279 &iter, "Server", &server_header);
1280 EXPECT_TRUE(has_server_header);
1281 EXPECT_EQ("Blah", server_header);
1282
1283 // Reading should give EOF right away, since there is no message body
1284 // (despite non-zero content-length).
1285 std::string response_data;
bnc691fda62016-08-12 00:43:161286 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011287 EXPECT_THAT(rv, IsOk());
[email protected]ef0faf2e72009-03-05 23:27:231288 EXPECT_EQ("", response_data);
1289}
1290
bncd16676a2016-07-20 16:23:011291TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
danakj1fd259a02016-04-16 03:17:091292 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
initial.commit586acc5fe2008-07-26 22:42:521293
1294 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351295 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1296 MockRead("hello"),
1297 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1298 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061299 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521300 };
Ryan Sleevib8d7ea02018-05-07 20:01:011301 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071302 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521303
[email protected]0b0bf032010-09-21 18:08:501304 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521305 "hello", "world"
1306 };
1307
1308 for (int i = 0; i < 2; ++i) {
[email protected]1c773ea12009-04-28 19:58:421309 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521310 request.method = "GET";
bncce36dca22015-04-21 22:11:231311 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:101312 request.traffic_annotation =
1313 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521314
bnc691fda62016-08-12 00:43:161315 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271316
[email protected]49639fa2011-12-20 23:22:411317 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521318
tfarina42834112016-09-22 13:38:201319 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011320 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521321
1322 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011323 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521324
bnc691fda62016-08-12 00:43:161325 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521326 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521327
wezca1070932016-05-26 20:30:521328 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251329 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
tbansal2ecbbc72016-10-06 17:15:471330 EXPECT_TRUE(response->proxy_server.is_direct());
initial.commit586acc5fe2008-07-26 22:42:521331
1332 std::string response_data;
bnc691fda62016-08-12 00:43:161333 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011334 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251335 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521336 }
1337}
1338
bncd16676a2016-07-20 16:23:011339TEST_F(HttpNetworkTransactionTest, Ignores100) {
danakj1fd259a02016-04-16 03:17:091340 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:221341 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:191342 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:221343 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:271344
[email protected]1c773ea12009-04-28 19:58:421345 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521346 request.method = "POST";
1347 request.url = GURL("http://www.foo.com/");
[email protected]329b68b2012-11-14 17:54:271348 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:101349 request.traffic_annotation =
1350 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521351
shivanishab9a143952016-09-19 17:23:411352 // Check the upload progress returned before initialization is correct.
1353 UploadProgress progress = request.upload_data_stream->GetUploadProgress();
1354 EXPECT_EQ(0u, progress.size());
1355 EXPECT_EQ(0u, progress.position());
1356
danakj1fd259a02016-04-16 03:17:091357 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161358 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271359
initial.commit586acc5fe2008-07-26 22:42:521360 MockRead data_reads[] = {
[email protected]217e6022008-09-29 18:18:351361 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
1362 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
1363 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061364 MockRead(SYNCHRONOUS, OK),
initial.commit586acc5fe2008-07-26 22:42:521365 };
Ryan Sleevib8d7ea02018-05-07 20:01:011366 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071367 session_deps_.socket_factory->AddSocketDataProvider(&data);
initial.commit586acc5fe2008-07-26 22:42:521368
[email protected]49639fa2011-12-20 23:22:411369 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521370
tfarina42834112016-09-22 13:38:201371 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011372 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521373
1374 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011375 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521376
bnc691fda62016-08-12 00:43:161377 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521378 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521379
wezca1070932016-05-26 20:30:521380 EXPECT_TRUE(response->headers);
[email protected]3d2a59b2008-09-26 19:44:251381 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521382
1383 std::string response_data;
bnc691fda62016-08-12 00:43:161384 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011385 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251386 EXPECT_EQ("hello world", response_data);
initial.commit586acc5fe2008-07-26 22:42:521387}
1388
[email protected]3a2d3662009-03-27 03:49:141389// This test is almost the same as Ignores100 above, but the response contains
1390// a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
[email protected]0877e3d2009-10-17 22:29:571391// HTTP/1.1 and the two status headers are read in one read.
bncd16676a2016-07-20 16:23:011392TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
[email protected]1c773ea12009-04-28 19:58:421393 HttpRequestInfo request;
[email protected]3a2d3662009-03-27 03:49:141394 request.method = "GET";
1395 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101396 request.traffic_annotation =
1397 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3a2d3662009-03-27 03:49:141398
danakj1fd259a02016-04-16 03:17:091399 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161400 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271401
[email protected]3a2d3662009-03-27 03:49:141402 MockRead data_reads[] = {
[email protected]0877e3d2009-10-17 22:29:571403 MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
1404 "HTTP/1.1 200 OK\r\n\r\n"),
[email protected]3a2d3662009-03-27 03:49:141405 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:061406 MockRead(SYNCHRONOUS, OK),
[email protected]3a2d3662009-03-27 03:49:141407 };
Ryan Sleevib8d7ea02018-05-07 20:01:011408 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071409 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3a2d3662009-03-27 03:49:141410
[email protected]49639fa2011-12-20 23:22:411411 TestCompletionCallback callback;
[email protected]3a2d3662009-03-27 03:49:141412
tfarina42834112016-09-22 13:38:201413 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011414 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3a2d3662009-03-27 03:49:141415
1416 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011417 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141418
bnc691fda62016-08-12 00:43:161419 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521420 ASSERT_TRUE(response);
[email protected]3a2d3662009-03-27 03:49:141421
wezca1070932016-05-26 20:30:521422 EXPECT_TRUE(response->headers);
[email protected]3a2d3662009-03-27 03:49:141423 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1424
1425 std::string response_data;
bnc691fda62016-08-12 00:43:161426 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011427 EXPECT_THAT(rv, IsOk());
[email protected]3a2d3662009-03-27 03:49:141428 EXPECT_EQ("hello world", response_data);
1429}
1430
Andrew Comminos517a92c2019-01-14 17:49:561431TEST_F(HttpNetworkTransactionTest, LoadTimingMeasuresTimeToFirstByteForHttp) {
1432 static const base::TimeDelta kDelayAfterFirstByte =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381433 base::TimeDelta::FromMilliseconds(10);
1434
1435 HttpRequestInfo request;
1436 request.method = "GET";
1437 request.url = GURL("http://www.foo.com/");
1438 request.traffic_annotation =
1439 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1440
1441 std::vector<MockWrite> data_writes = {
1442 MockWrite(ASYNC, 0,
1443 "GET / HTTP/1.1\r\n"
1444 "Host: www.foo.com\r\n"
1445 "Connection: keep-alive\r\n\r\n"),
1446 };
1447
1448 std::vector<MockRead> data_reads = {
1449 // Write one byte of the status line, followed by a pause.
1450 MockRead(ASYNC, 1, "H"),
1451 MockRead(ASYNC, ERR_IO_PENDING, 2),
1452 MockRead(ASYNC, 3, "TTP/1.1 200 OK\r\n\r\n"),
1453 MockRead(ASYNC, 4, "hello world"),
1454 MockRead(SYNCHRONOUS, OK, 5),
1455 };
1456
1457 SequencedSocketData data(data_reads, data_writes);
1458 session_deps_.socket_factory->AddSocketDataProvider(&data);
1459
1460 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1461
1462 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1463
1464 TestCompletionCallback callback;
1465
1466 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1467 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1468
1469 data.RunUntilPaused();
1470 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561471 FastForwardBy(kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381472 data.Resume();
1473
1474 rv = callback.WaitForResult();
1475 EXPECT_THAT(rv, IsOk());
1476
1477 const HttpResponseInfo* response = trans.GetResponseInfo();
1478 ASSERT_TRUE(response);
1479
1480 EXPECT_TRUE(response->headers);
1481 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1482
1483 LoadTimingInfo load_timing_info;
1484 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1485 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1486 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561487 // Ensure we didn't include the delay in the TTFB time.
1488 EXPECT_EQ(load_timing_info.receive_headers_start,
1489 load_timing_info.connect_timing.connect_end);
1490 // Ensure that the mock clock advanced at all.
1491 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1492 kDelayAfterFirstByte);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381493
1494 std::string response_data;
1495 rv = ReadTransaction(&trans, &response_data);
1496 EXPECT_THAT(rv, IsOk());
1497 EXPECT_EQ("hello world", response_data);
1498}
1499
1500// Tests that the time-to-first-byte reported in a transaction's load timing
1501// info uses the first response, even if 1XX/informational.
1502void HttpNetworkTransactionTest::Check100ResponseTiming(bool use_spdy) {
Andrew Comminos517a92c2019-01-14 17:49:561503 static const base::TimeDelta kDelayAfter100Response =
Andrew Comminos1f2ff1cc2018-12-14 05:22:381504 base::TimeDelta::FromMilliseconds(10);
1505
1506 HttpRequestInfo request;
1507 request.method = "GET";
1508 request.url = GURL("https://www.foo.com/");
1509 request.traffic_annotation =
1510 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1511
1512 SSLSocketDataProvider ssl(ASYNC, OK);
1513 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
1514
1515 std::vector<MockWrite> data_writes;
1516 std::vector<MockRead> data_reads;
1517
1518 spdy::SpdySerializedFrame spdy_req(
1519 spdy_util_.ConstructSpdyGet(request.url.spec().c_str(), 1, LOWEST));
1520
1521 spdy::SpdyHeaderBlock spdy_resp1_headers;
1522 spdy_resp1_headers[spdy::kHttp2StatusHeader] = "100";
1523 spdy::SpdySerializedFrame spdy_resp1(
1524 spdy_util_.ConstructSpdyReply(1, spdy_resp1_headers.Clone()));
1525 spdy::SpdySerializedFrame spdy_resp2(
1526 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
1527 spdy::SpdySerializedFrame spdy_data(
1528 spdy_util_.ConstructSpdyDataFrame(1, "hello world", true));
1529
1530 if (use_spdy) {
1531 ssl.next_proto = kProtoHTTP2;
1532
1533 data_writes = {CreateMockWrite(spdy_req, 0)};
1534
1535 data_reads = {
1536 CreateMockRead(spdy_resp1, 1), MockRead(ASYNC, ERR_IO_PENDING, 2),
1537 CreateMockRead(spdy_resp2, 3), CreateMockRead(spdy_data, 4),
1538 MockRead(SYNCHRONOUS, OK, 5),
1539 };
1540 } else {
1541 data_writes = {
1542 MockWrite(ASYNC, 0,
1543 "GET / HTTP/1.1\r\n"
1544 "Host: www.foo.com\r\n"
1545 "Connection: keep-alive\r\n\r\n"),
1546 };
1547
1548 data_reads = {
1549 MockRead(ASYNC, 1, "HTTP/1.1 100 Continue\r\n\r\n"),
1550 MockRead(ASYNC, ERR_IO_PENDING, 2),
1551
1552 MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"),
1553 MockRead(ASYNC, 4, "hello world"),
1554 MockRead(SYNCHRONOUS, OK, 5),
1555 };
1556 }
1557
1558 SequencedSocketData data(data_reads, data_writes);
1559 session_deps_.socket_factory->AddSocketDataProvider(&data);
1560
1561 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1562
1563 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1564
1565 TestCompletionCallback callback;
1566
1567 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1568 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1569
1570 data.RunUntilPaused();
1571 // We should now have parsed the 100 response and hit ERR_IO_PENDING. Insert
1572 // the delay before parsing the 200 response.
1573 ASSERT_TRUE(data.IsPaused());
Andrew Comminos517a92c2019-01-14 17:49:561574 FastForwardBy(kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381575 data.Resume();
1576
1577 rv = callback.WaitForResult();
1578 EXPECT_THAT(rv, IsOk());
1579
1580 const HttpResponseInfo* response = trans.GetResponseInfo();
1581 ASSERT_TRUE(response);
1582
1583 LoadTimingInfo load_timing_info;
1584 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
1585 EXPECT_FALSE(load_timing_info.receive_headers_start.is_null());
1586 EXPECT_FALSE(load_timing_info.connect_timing.connect_end.is_null());
Andrew Comminos517a92c2019-01-14 17:49:561587 // Ensure we didn't include the delay in the TTFB time.
1588 EXPECT_EQ(load_timing_info.receive_headers_start,
1589 load_timing_info.connect_timing.connect_end);
1590 // Ensure that the mock clock advanced at all.
1591 EXPECT_EQ(base::TimeTicks::Now() - load_timing_info.receive_headers_start,
1592 kDelayAfter100Response);
Andrew Comminos1f2ff1cc2018-12-14 05:22:381593
1594 std::string response_data;
1595 rv = ReadTransaction(&trans, &response_data);
1596 EXPECT_THAT(rv, IsOk());
1597 EXPECT_EQ("hello world", response_data);
1598}
1599
Andrew Comminos517a92c2019-01-14 17:49:561600TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForHttp) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381601 Check100ResponseTiming(false /* use_spdy */);
1602}
1603
Andrew Comminos517a92c2019-01-14 17:49:561604TEST_F(HttpNetworkTransactionTest, MeasuresTimeToFirst100ResponseForSpdy) {
Andrew Comminos1f2ff1cc2018-12-14 05:22:381605 Check100ResponseTiming(true /* use_spdy */);
1606}
1607
bncd16676a2016-07-20 16:23:011608TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
zmo9528c9f42015-08-04 22:12:081609 HttpRequestInfo request;
1610 request.method = "POST";
1611 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101612 request.traffic_annotation =
1613 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
zmo9528c9f42015-08-04 22:12:081614
danakj1fd259a02016-04-16 03:17:091615 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161616 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zmo9528c9f42015-08-04 22:12:081617
1618 MockRead data_reads[] = {
1619 MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
1620 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381621 };
Ryan Sleevib8d7ea02018-05-07 20:01:011622 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
zmo9528c9f42015-08-04 22:12:081623 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381624
zmo9528c9f42015-08-04 22:12:081625 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381626
tfarina42834112016-09-22 13:38:201627 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011628 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381629
zmo9528c9f42015-08-04 22:12:081630 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011631 EXPECT_THAT(rv, IsOk());
[email protected]ee9410e72010-01-07 01:42:381632
zmo9528c9f42015-08-04 22:12:081633 std::string response_data;
bnc691fda62016-08-12 00:43:161634 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011635 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:081636 EXPECT_EQ("", response_data);
[email protected]ee9410e72010-01-07 01:42:381637}
1638
bncd16676a2016-07-20 16:23:011639TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
[email protected]ee9410e72010-01-07 01:42:381640 HttpRequestInfo request;
1641 request.method = "POST";
1642 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101643 request.traffic_annotation =
1644 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ee9410e72010-01-07 01:42:381645
danakj1fd259a02016-04-16 03:17:091646 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:161647 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:271648
[email protected]ee9410e72010-01-07 01:42:381649 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:061650 MockRead(ASYNC, 0),
[email protected]ee9410e72010-01-07 01:42:381651 };
Ryan Sleevib8d7ea02018-05-07 20:01:011652 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071653 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]ee9410e72010-01-07 01:42:381654
[email protected]49639fa2011-12-20 23:22:411655 TestCompletionCallback callback;
[email protected]ee9410e72010-01-07 01:42:381656
tfarina42834112016-09-22 13:38:201657 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011658 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ee9410e72010-01-07 01:42:381659
1660 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011661 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]ee9410e72010-01-07 01:42:381662}
1663
[email protected]23e482282013-06-14 16:08:021664void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
[email protected]202965992011-12-07 23:04:511665 const MockWrite* write_failure,
1666 const MockRead* read_failure) {
[email protected]1c773ea12009-04-28 19:58:421667 HttpRequestInfo request;
initial.commit586acc5fe2008-07-26 22:42:521668 request.method = "GET";
1669 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101670 request.traffic_annotation =
1671 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
initial.commit586acc5fe2008-07-26 22:42:521672
vishal.b62985ca92015-04-17 08:45:511673 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:071674 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091675 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:271676
[email protected]202965992011-12-07 23:04:511677 // Written data for successfully sending both requests.
1678 MockWrite data1_writes[] = {
1679 MockWrite("GET / HTTP/1.1\r\n"
1680 "Host: www.foo.com\r\n"
1681 "Connection: keep-alive\r\n\r\n"),
1682 MockWrite("GET / HTTP/1.1\r\n"
1683 "Host: www.foo.com\r\n"
1684 "Connection: keep-alive\r\n\r\n")
1685 };
1686
1687 // Read results for the first request.
initial.commit586acc5fe2008-07-26 22:42:521688 MockRead data1_reads[] = {
[email protected]217e6022008-09-29 18:18:351689 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1690 MockRead("hello"),
[email protected]8ddf8322012-02-23 18:08:061691 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521692 };
[email protected]202965992011-12-07 23:04:511693
1694 if (write_failure) {
[email protected]a34f61ee2014-03-18 20:59:491695 ASSERT_FALSE(read_failure);
[email protected]202965992011-12-07 23:04:511696 data1_writes[1] = *write_failure;
1697 } else {
1698 ASSERT_TRUE(read_failure);
1699 data1_reads[2] = *read_failure;
1700 }
1701
Ryan Sleevib8d7ea02018-05-07 20:01:011702 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]bb88e1d32013-05-03 23:11:071703 session_deps_.socket_factory->AddSocketDataProvider(&data1);
initial.commit586acc5fe2008-07-26 22:42:521704
1705 MockRead data2_reads[] = {
[email protected]217e6022008-09-29 18:18:351706 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
1707 MockRead("world"),
[email protected]8ddf8322012-02-23 18:08:061708 MockRead(ASYNC, OK),
initial.commit586acc5fe2008-07-26 22:42:521709 };
Ryan Sleevib8d7ea02018-05-07 20:01:011710 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:071711 session_deps_.socket_factory->AddSocketDataProvider(&data2);
initial.commit586acc5fe2008-07-26 22:42:521712
thestig9d3bb0c2015-01-24 00:49:511713 const char* const kExpectedResponseData[] = {
initial.commit586acc5fe2008-07-26 22:42:521714 "hello", "world"
1715 };
1716
mikecironef22f9812016-10-04 03:40:191717 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
initial.commit586acc5fe2008-07-26 22:42:521718 for (int i = 0; i < 2; ++i) {
[email protected]49639fa2011-12-20 23:22:411719 TestCompletionCallback callback;
initial.commit586acc5fe2008-07-26 22:42:521720
bnc691fda62016-08-12 00:43:161721 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
initial.commit586acc5fe2008-07-26 22:42:521722
tfarina42834112016-09-22 13:38:201723 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011724 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
initial.commit586acc5fe2008-07-26 22:42:521725
1726 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011727 EXPECT_THAT(rv, IsOk());
initial.commit586acc5fe2008-07-26 22:42:521728
[email protected]58e32bb2013-01-21 18:23:251729 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161730 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:251731 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
1732 if (i == 0) {
1733 first_socket_log_id = load_timing_info.socket_log_id;
1734 } else {
1735 // The second request should be using a new socket.
1736 EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
1737 }
1738
bnc691fda62016-08-12 00:43:161739 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521740 ASSERT_TRUE(response);
initial.commit586acc5fe2008-07-26 22:42:521741
wezca1070932016-05-26 20:30:521742 EXPECT_TRUE(response->headers);
tbansal2ecbbc72016-10-06 17:15:471743 EXPECT_TRUE(response->proxy_server.is_direct());
[email protected]3d2a59b2008-09-26 19:44:251744 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
initial.commit586acc5fe2008-07-26 22:42:521745
1746 std::string response_data;
bnc691fda62016-08-12 00:43:161747 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011748 EXPECT_THAT(rv, IsOk());
[email protected]3d2a59b2008-09-26 19:44:251749 EXPECT_EQ(kExpectedResponseData[i], response_data);
initial.commit586acc5fe2008-07-26 22:42:521750 }
1751}
[email protected]3d2a59b2008-09-26 19:44:251752
[email protected]a34f61ee2014-03-18 20:59:491753void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
1754 const MockWrite* write_failure,
[email protected]09356c652014-03-25 15:36:101755 const MockRead* read_failure,
1756 bool use_spdy) {
[email protected]a34f61ee2014-03-18 20:59:491757 HttpRequestInfo request;
1758 request.method = "GET";
[email protected]09356c652014-03-25 15:36:101759 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101760 request.traffic_annotation =
1761 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a34f61ee2014-03-18 20:59:491762
vishal.b62985ca92015-04-17 08:45:511763 TestNetLog net_log;
[email protected]a34f61ee2014-03-18 20:59:491764 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:091765 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a34f61ee2014-03-18 20:59:491766
[email protected]09356c652014-03-25 15:36:101767 SSLSocketDataProvider ssl1(ASYNC, OK);
1768 SSLSocketDataProvider ssl2(ASYNC, OK);
1769 if (use_spdy) {
bnc3cf2a592016-08-11 14:48:361770 ssl1.next_proto = kProtoHTTP2;
1771 ssl2.next_proto = kProtoHTTP2;
[email protected]09356c652014-03-25 15:36:101772 }
1773 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
1774 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]a34f61ee2014-03-18 20:59:491775
[email protected]09356c652014-03-25 15:36:101776 // SPDY versions of the request and response.
Ryan Hamilton0239aac2018-05-19 00:03:131777 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
bnc38dcd392016-02-09 23:19:491778 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131779 spdy::SpdySerializedFrame spdy_response(
Raul Tambre94493c652019-03-11 17:18:351780 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131781 spdy::SpdySerializedFrame spdy_data(
Bence Békyd74f4382018-02-20 18:26:191782 spdy_util_.ConstructSpdyDataFrame(1, "hello", true));
[email protected]a34f61ee2014-03-18 20:59:491783
[email protected]09356c652014-03-25 15:36:101784 // HTTP/1.1 versions of the request and response.
1785 const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
1786 "Host: www.foo.com\r\n"
1787 "Connection: keep-alive\r\n\r\n";
1788 const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
1789 const char kHttpData[] = "hello";
1790
1791 std::vector<MockRead> data1_reads;
1792 std::vector<MockWrite> data1_writes;
[email protected]a34f61ee2014-03-18 20:59:491793 if (write_failure) {
1794 ASSERT_FALSE(read_failure);
[email protected]09356c652014-03-25 15:36:101795 data1_writes.push_back(*write_failure);
1796 data1_reads.push_back(MockRead(ASYNC, OK));
[email protected]a34f61ee2014-03-18 20:59:491797 } else {
1798 ASSERT_TRUE(read_failure);
[email protected]09356c652014-03-25 15:36:101799 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411800 data1_writes.push_back(CreateMockWrite(spdy_request));
[email protected]09356c652014-03-25 15:36:101801 } else {
1802 data1_writes.push_back(MockWrite(kHttpRequest));
1803 }
1804 data1_reads.push_back(*read_failure);
[email protected]a34f61ee2014-03-18 20:59:491805 }
1806
Ryan Sleevib8d7ea02018-05-07 20:01:011807 StaticSocketDataProvider data1(data1_reads, data1_writes);
[email protected]a34f61ee2014-03-18 20:59:491808 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1809
[email protected]09356c652014-03-25 15:36:101810 std::vector<MockRead> data2_reads;
1811 std::vector<MockWrite> data2_writes;
1812
1813 if (use_spdy) {
bncdf80d44fd2016-07-15 20:27:411814 data2_writes.push_back(CreateMockWrite(spdy_request, 0, ASYNC));
[email protected]09356c652014-03-25 15:36:101815
bncdf80d44fd2016-07-15 20:27:411816 data2_reads.push_back(CreateMockRead(spdy_response, 1, ASYNC));
1817 data2_reads.push_back(CreateMockRead(spdy_data, 2, ASYNC));
[email protected]09356c652014-03-25 15:36:101818 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1819 } else {
1820 data2_writes.push_back(
1821 MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
1822
1823 data2_reads.push_back(
1824 MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
1825 data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
1826 data2_reads.push_back(MockRead(ASYNC, OK, 3));
1827 }
Ryan Sleevib8d7ea02018-05-07 20:01:011828 SequencedSocketData data2(data2_reads, data2_writes);
[email protected]a34f61ee2014-03-18 20:59:491829 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1830
1831 // Preconnect a socket.
nharper8cdb0fb2016-04-22 21:34:591832 session->http_stream_factory()->PreconnectStreams(1, request);
[email protected]a34f61ee2014-03-18 20:59:491833 // Wait for the preconnect to complete.
1834 // TODO(davidben): Some way to wait for an idle socket count might be handy.
1835 base::RunLoop().RunUntilIdle();
Matt Menke9d5e2c92019-02-05 01:42:231836 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]a34f61ee2014-03-18 20:59:491837
1838 // Make the request.
1839 TestCompletionCallback callback;
1840
bnc691fda62016-08-12 00:43:161841 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a34f61ee2014-03-18 20:59:491842
tfarina42834112016-09-22 13:38:201843 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:011844 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a34f61ee2014-03-18 20:59:491845
1846 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:011847 EXPECT_THAT(rv, IsOk());
[email protected]a34f61ee2014-03-18 20:59:491848
1849 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:161850 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]09356c652014-03-25 15:36:101851 TestLoadTimingNotReused(
1852 load_timing_info,
1853 CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]a34f61ee2014-03-18 20:59:491854
bnc691fda62016-08-12 00:43:161855 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:521856 ASSERT_TRUE(response);
[email protected]a34f61ee2014-03-18 20:59:491857
wezca1070932016-05-26 20:30:521858 EXPECT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:021859 if (response->was_fetched_via_spdy) {
1860 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
1861 } else {
1862 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
1863 }
[email protected]a34f61ee2014-03-18 20:59:491864
1865 std::string response_data;
bnc691fda62016-08-12 00:43:161866 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:011867 EXPECT_THAT(rv, IsOk());
[email protected]09356c652014-03-25 15:36:101868 EXPECT_EQ(kHttpData, response_data);
[email protected]a34f61ee2014-03-18 20:59:491869}
1870
Biljith Jayan45a41722017-08-16 18:43:141871// Test that we do not retry indefinitely when a server sends an error like
1872// ERR_SPDY_PING_FAILED, ERR_SPDY_SERVER_REFUSED_STREAM,
1873// ERR_QUIC_HANDSHAKE_FAILED or ERR_QUIC_PROTOCOL_ERROR.
1874TEST_F(HttpNetworkTransactionTest, FiniteRetriesOnIOError) {
1875 HttpRequestInfo request;
1876 request.method = "GET";
1877 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101878 request.traffic_annotation =
1879 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141880
1881 // Check whether we give up after the third try.
1882
1883 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131884 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141885 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131886 spdy::SpdySerializedFrame spdy_response_go_away(
1887 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011888 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1889 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141890
1891 // Three go away responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011892 StaticSocketDataProvider data1(data_read1, data_write);
1893 StaticSocketDataProvider data2(data_read1, data_write);
1894 StaticSocketDataProvider data3(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141895
1896 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1897 AddSSLSocketData();
1898 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1899 AddSSLSocketData();
1900 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1901 AddSSLSocketData();
1902
1903 TestCompletionCallback callback;
1904 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1905 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1906
1907 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1908 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1909
1910 rv = callback.WaitForResult();
1911 EXPECT_THAT(rv, IsError(ERR_SPDY_SERVER_REFUSED_STREAM));
1912}
1913
1914TEST_F(HttpNetworkTransactionTest, RetryTwiceOnIOError) {
1915 HttpRequestInfo request;
1916 request.method = "GET";
1917 request.url = GURL("https://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:101918 request.traffic_annotation =
1919 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Biljith Jayan45a41722017-08-16 18:43:141920
1921 // Check whether we try atleast thrice before giving up.
1922
1923 // Construct an HTTP2 request and a "Go away" response.
Ryan Hamilton0239aac2018-05-19 00:03:131924 spdy::SpdySerializedFrame spdy_request(spdy_util_.ConstructSpdyGet(
Biljith Jayan45a41722017-08-16 18:43:141925 request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
Ryan Hamilton0239aac2018-05-19 00:03:131926 spdy::SpdySerializedFrame spdy_response_go_away(
1927 spdy_util_.ConstructSpdyGoAway(0));
Ryan Sleevib8d7ea02018-05-07 20:01:011928 MockRead data_read1[] = {CreateMockRead(spdy_response_go_away)};
1929 MockWrite data_write[] = {CreateMockWrite(spdy_request, 0)};
Biljith Jayan45a41722017-08-16 18:43:141930
1931 // Construct a non error HTTP2 response.
Ryan Hamilton0239aac2018-05-19 00:03:131932 spdy::SpdySerializedFrame spdy_response_no_error(
Biljith Jayan45a41722017-08-16 18:43:141933 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:131934 spdy::SpdySerializedFrame spdy_data(
1935 spdy_util_.ConstructSpdyDataFrame(1, true));
Biljith Jayan45a41722017-08-16 18:43:141936 MockRead data_read2[] = {CreateMockRead(spdy_response_no_error, 1),
1937 CreateMockRead(spdy_data, 2)};
1938
1939 // Two error responses.
Ryan Sleevib8d7ea02018-05-07 20:01:011940 StaticSocketDataProvider data1(data_read1, data_write);
1941 StaticSocketDataProvider data2(data_read1, data_write);
Biljith Jayan45a41722017-08-16 18:43:141942 // Followed by a success response.
Ryan Sleevib8d7ea02018-05-07 20:01:011943 SequencedSocketData data3(data_read2, data_write);
Biljith Jayan45a41722017-08-16 18:43:141944
1945 session_deps_.socket_factory->AddSocketDataProvider(&data1);
1946 AddSSLSocketData();
1947 session_deps_.socket_factory->AddSocketDataProvider(&data2);
1948 AddSSLSocketData();
1949 session_deps_.socket_factory->AddSocketDataProvider(&data3);
1950 AddSSLSocketData();
1951
1952 TestCompletionCallback callback;
1953 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
1954 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
1955
1956 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
1957 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1958
1959 rv = callback.WaitForResult();
1960 EXPECT_THAT(rv, IsOk());
1961}
1962
bncd16676a2016-07-20 16:23:011963TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionNotConnectedOnWrite) {
[email protected]8ddf8322012-02-23 18:08:061964 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:351965 KeepAliveConnectionResendRequestTest(&write_failure, nullptr);
[email protected]202965992011-12-07 23:04:511966}
1967
bncd16676a2016-07-20 16:23:011968TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
[email protected]8ddf8322012-02-23 18:08:061969 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:351970 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251971}
1972
bncd16676a2016-07-20 16:23:011973TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
[email protected]8ddf8322012-02-23 18:08:061974 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:351975 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]3d2a59b2008-09-26 19:44:251976}
1977
[email protected]d58ceea82014-06-04 10:55:541978// Make sure that on a 408 response (Request Timeout), the request is retried,
1979// if the socket was a reused keep alive socket.
bncd16676a2016-07-20 16:23:011980TEST_F(HttpNetworkTransactionTest, KeepAlive408) {
[email protected]d58ceea82014-06-04 10:55:541981 MockRead read_failure(SYNCHRONOUS,
1982 "HTTP/1.1 408 Request Timeout\r\n"
1983 "Connection: Keep-Alive\r\n"
1984 "Content-Length: 6\r\n\r\n"
1985 "Pickle");
Raul Tambre94493c652019-03-11 17:18:351986 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
[email protected]d58ceea82014-06-04 10:55:541987}
1988
bncd16676a2016-07-20 16:23:011989TEST_F(HttpNetworkTransactionTest, PreconnectErrorNotConnectedOnWrite) {
[email protected]a34f61ee2014-03-18 20:59:491990 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:351991 PreconnectErrorResendRequestTest(&write_failure, nullptr, false);
[email protected]a34f61ee2014-03-18 20:59:491992}
1993
bncd16676a2016-07-20 16:23:011994TEST_F(HttpNetworkTransactionTest, PreconnectErrorReset) {
[email protected]a34f61ee2014-03-18 20:59:491995 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:351996 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]a34f61ee2014-03-18 20:59:491997}
1998
bncd16676a2016-07-20 16:23:011999TEST_F(HttpNetworkTransactionTest, PreconnectErrorEOF) {
[email protected]a34f61ee2014-03-18 20:59:492000 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:352001 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]09356c652014-03-25 15:36:102002}
2003
bncd16676a2016-07-20 16:23:012004TEST_F(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:102005 MockRead read_failure(ASYNC, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:352006 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]09356c652014-03-25 15:36:102007}
2008
[email protected]d58ceea82014-06-04 10:55:542009// Make sure that on a 408 response (Request Timeout), the request is retried,
2010// if the socket was a preconnected (UNUSED_IDLE) socket.
bncd16676a2016-07-20 16:23:012011TEST_F(HttpNetworkTransactionTest, RetryOnIdle408) {
[email protected]d58ceea82014-06-04 10:55:542012 MockRead read_failure(SYNCHRONOUS,
2013 "HTTP/1.1 408 Request Timeout\r\n"
2014 "Connection: Keep-Alive\r\n"
2015 "Content-Length: 6\r\n\r\n"
2016 "Pickle");
Raul Tambre94493c652019-03-11 17:18:352017 KeepAliveConnectionResendRequestTest(nullptr, &read_failure);
2018 PreconnectErrorResendRequestTest(nullptr, &read_failure, false);
[email protected]d58ceea82014-06-04 10:55:542019}
2020
bncd16676a2016-07-20 16:23:012021TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorNotConnectedOnWrite) {
[email protected]09356c652014-03-25 15:36:102022 MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
Raul Tambre94493c652019-03-11 17:18:352023 PreconnectErrorResendRequestTest(&write_failure, nullptr, true);
[email protected]09356c652014-03-25 15:36:102024}
2025
bncd16676a2016-07-20 16:23:012026TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
[email protected]09356c652014-03-25 15:36:102027 MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
Raul Tambre94493c652019-03-11 17:18:352028 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]09356c652014-03-25 15:36:102029}
2030
bncd16676a2016-07-20 16:23:012031TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
[email protected]09356c652014-03-25 15:36:102032 MockRead read_failure(SYNCHRONOUS, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:352033 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]09356c652014-03-25 15:36:102034}
2035
bncd16676a2016-07-20 16:23:012036TEST_F(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
[email protected]09356c652014-03-25 15:36:102037 MockRead read_failure(ASYNC, OK); // EOF
Raul Tambre94493c652019-03-11 17:18:352038 PreconnectErrorResendRequestTest(nullptr, &read_failure, true);
[email protected]a34f61ee2014-03-18 20:59:492039}
2040
bncd16676a2016-07-20 16:23:012041TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
[email protected]1c773ea12009-04-28 19:58:422042 HttpRequestInfo request;
[email protected]3d2a59b2008-09-26 19:44:252043 request.method = "GET";
bncce36dca22015-04-21 22:11:232044 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102045 request.traffic_annotation =
2046 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3d2a59b2008-09-26 19:44:252047
danakj1fd259a02016-04-16 03:17:092048 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162049 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272050
[email protected]3d2a59b2008-09-26 19:44:252051 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062052 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]217e6022008-09-29 18:18:352053 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2054 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062055 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252056 };
Ryan Sleevib8d7ea02018-05-07 20:01:012057 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072058 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3d2a59b2008-09-26 19:44:252059
[email protected]49639fa2011-12-20 23:22:412060 TestCompletionCallback callback;
[email protected]3d2a59b2008-09-26 19:44:252061
tfarina42834112016-09-22 13:38:202062 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012063 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3d2a59b2008-09-26 19:44:252064
2065 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012066 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:592067
2068 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162069 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592070 EXPECT_LT(0u, endpoint.address().size());
[email protected]3d2a59b2008-09-26 19:44:252071}
2072
2073// What do various browsers do when the server closes a non-keepalive
2074// connection without sending any response header or body?
2075//
2076// IE7: error page
2077// Safari 3.1.2 (Windows): error page
2078// Firefox 3.0.1: blank page
2079// Opera 9.52: after five attempts, blank page
[email protected]1c773ea12009-04-28 19:58:422080// Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
2081// Us: error page (EMPTY_RESPONSE)
bncd16676a2016-07-20 16:23:012082TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
[email protected]3d2a59b2008-09-26 19:44:252083 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:062084 MockRead(SYNCHRONOUS, OK), // EOF
[email protected]217e6022008-09-29 18:18:352085 MockRead("HTTP/1.0 200 OK\r\n\r\n"), // Should not be used
2086 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:062087 MockRead(SYNCHRONOUS, OK),
[email protected]3d2a59b2008-09-26 19:44:252088 };
Ryan Sleevib8d7ea02018-05-07 20:01:012089 SimpleGetHelperResult out = SimpleGetHelper(data_reads);
robpercival214763f2016-07-01 23:27:012090 EXPECT_THAT(out.rv, IsError(ERR_EMPTY_RESPONSE));
[email protected]3d2a59b2008-09-26 19:44:252091}
[email protected]1826a402014-01-08 15:40:482092
[email protected]7a5378b2012-11-04 03:25:172093// Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
2094// tests. There was a bug causing HttpNetworkTransaction to hang in the
2095// destructor in such situations.
2096// See http://crbug.com/154712 and http://crbug.com/156609.
bncd16676a2016-07-20 16:23:012097TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
[email protected]7a5378b2012-11-04 03:25:172098 HttpRequestInfo request;
2099 request.method = "GET";
bncce36dca22015-04-21 22:11:232100 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102101 request.traffic_annotation =
2102 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172103
danakj1fd259a02016-04-16 03:17:092104 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582105 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192106 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172107
2108 MockRead data_reads[] = {
2109 MockRead("HTTP/1.0 200 OK\r\n"),
2110 MockRead("Connection: keep-alive\r\n"),
2111 MockRead("Content-Length: 100\r\n\r\n"),
2112 MockRead("hello"),
2113 MockRead(SYNCHRONOUS, 0),
2114 };
Ryan Sleevib8d7ea02018-05-07 20:01:012115 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072116 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172117
2118 TestCompletionCallback callback;
2119
tfarina42834112016-09-22 13:38:202120 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012121 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172122
2123 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012124 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172125
Victor Costan9c7302b2018-08-27 16:39:442126 scoped_refptr<IOBufferWithSize> io_buf =
2127 base::MakeRefCounted<IOBufferWithSize>(100);
[email protected]90499482013-06-01 00:39:502128 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172129 if (rv == ERR_IO_PENDING)
2130 rv = callback.WaitForResult();
2131 EXPECT_EQ(5, rv);
[email protected]90499482013-06-01 00:39:502132 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
robpercival214763f2016-07-01 23:27:012133 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172134
2135 trans.reset();
fdoray92e35a72016-06-10 15:54:552136 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172137 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2138}
2139
bncd16676a2016-07-20 16:23:012140TEST_F(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
[email protected]7a5378b2012-11-04 03:25:172141 HttpRequestInfo request;
2142 request.method = "GET";
bncce36dca22015-04-21 22:11:232143 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102144 request.traffic_annotation =
2145 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7a5378b2012-11-04 03:25:172146
danakj1fd259a02016-04-16 03:17:092147 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:582148 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192149 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7a5378b2012-11-04 03:25:172150
2151 MockRead data_reads[] = {
2152 MockRead("HTTP/1.0 200 OK\r\n"),
2153 MockRead("Connection: keep-alive\r\n"),
2154 MockRead("Content-Length: 100\r\n\r\n"),
2155 MockRead(SYNCHRONOUS, 0),
2156 };
Ryan Sleevib8d7ea02018-05-07 20:01:012157 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:072158 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]7a5378b2012-11-04 03:25:172159
2160 TestCompletionCallback callback;
2161
tfarina42834112016-09-22 13:38:202162 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012163 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a5378b2012-11-04 03:25:172164
2165 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012166 EXPECT_THAT(rv, IsOk());
[email protected]7a5378b2012-11-04 03:25:172167
Victor Costan9c7302b2018-08-27 16:39:442168 scoped_refptr<IOBufferWithSize> io_buf(
2169 base::MakeRefCounted<IOBufferWithSize>(100));
[email protected]90499482013-06-01 00:39:502170 rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7a5378b2012-11-04 03:25:172171 if (rv == ERR_IO_PENDING)
2172 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:012173 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]7a5378b2012-11-04 03:25:172174
2175 trans.reset();
fdoray92e35a72016-06-10 15:54:552176 base::RunLoop().RunUntilIdle();
[email protected]7a5378b2012-11-04 03:25:172177 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2178}
2179
[email protected]0b0bf032010-09-21 18:08:502180// Test that we correctly reuse a keep-alive connection after not explicitly
2181// reading the body.
bncd16676a2016-07-20 16:23:012182TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
[email protected]fc31d6a42010-06-24 18:05:132183 HttpRequestInfo request;
2184 request.method = "GET";
2185 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102186 request.traffic_annotation =
2187 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]fc31d6a42010-06-24 18:05:132188
vishal.b62985ca92015-04-17 08:45:512189 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:072190 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:092191 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272192
mmenkecc2298e2015-12-07 18:20:182193 const char* request_data =
2194 "GET / HTTP/1.1\r\n"
2195 "Host: www.foo.com\r\n"
2196 "Connection: keep-alive\r\n\r\n";
2197 MockWrite data_writes[] = {
2198 MockWrite(ASYNC, 0, request_data), MockWrite(ASYNC, 2, request_data),
2199 MockWrite(ASYNC, 4, request_data), MockWrite(ASYNC, 6, request_data),
2200 MockWrite(ASYNC, 8, request_data), MockWrite(ASYNC, 10, request_data),
2201 MockWrite(ASYNC, 12, request_data), MockWrite(ASYNC, 14, request_data),
2202 MockWrite(ASYNC, 17, request_data), MockWrite(ASYNC, 20, request_data),
2203 };
2204
[email protected]0b0bf032010-09-21 18:08:502205 // Note that because all these reads happen in the same
2206 // StaticSocketDataProvider, it shows that the same socket is being reused for
2207 // all transactions.
mmenkecc2298e2015-12-07 18:20:182208 MockRead data_reads[] = {
2209 MockRead(ASYNC, 1, "HTTP/1.1 204 No Content\r\n\r\n"),
2210 MockRead(ASYNC, 3, "HTTP/1.1 205 Reset Content\r\n\r\n"),
2211 MockRead(ASYNC, 5, "HTTP/1.1 304 Not Modified\r\n\r\n"),
2212 MockRead(ASYNC, 7,
2213 "HTTP/1.1 302 Found\r\n"
2214 "Content-Length: 0\r\n\r\n"),
2215 MockRead(ASYNC, 9,
2216 "HTTP/1.1 302 Found\r\n"
2217 "Content-Length: 5\r\n\r\n"
2218 "hello"),
2219 MockRead(ASYNC, 11,
2220 "HTTP/1.1 301 Moved Permanently\r\n"
2221 "Content-Length: 0\r\n\r\n"),
2222 MockRead(ASYNC, 13,
2223 "HTTP/1.1 301 Moved Permanently\r\n"
2224 "Content-Length: 5\r\n\r\n"
2225 "hello"),
[email protected]fc31d6a42010-06-24 18:05:132226
mmenkecc2298e2015-12-07 18:20:182227 // In the next two rounds, IsConnectedAndIdle returns false, due to
2228 // the set_busy_before_sync_reads(true) call, while the
2229 // HttpNetworkTransaction is being shut down, but the socket is still
2230 // reuseable. See http://crbug.com/544255.
2231 MockRead(ASYNC, 15,
2232 "HTTP/1.1 200 Hunky-Dory\r\n"
2233 "Content-Length: 5\r\n\r\n"),
2234 MockRead(SYNCHRONOUS, 16, "hello"),
[email protected]fc31d6a42010-06-24 18:05:132235
mmenkecc2298e2015-12-07 18:20:182236 MockRead(ASYNC, 18,
2237 "HTTP/1.1 200 Hunky-Dory\r\n"
2238 "Content-Length: 5\r\n\r\n"
2239 "he"),
2240 MockRead(SYNCHRONOUS, 19, "llo"),
2241
2242 // The body of the final request is actually read.
2243 MockRead(ASYNC, 21, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
2244 MockRead(ASYNC, 22, "hello"),
2245 };
Ryan Sleevib8d7ea02018-05-07 20:01:012246 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182247 data.set_busy_before_sync_reads(true);
2248 session_deps_.socket_factory->AddSocketDataProvider(&data);
2249
Avi Drissman4365a4782018-12-28 19:26:242250 const int kNumUnreadBodies = base::size(data_writes) - 1;
[email protected]0b0bf032010-09-21 18:08:502251 std::string response_lines[kNumUnreadBodies];
2252
mikecironef22f9812016-10-04 03:40:192253 uint32_t first_socket_log_id = NetLogSource::kInvalidId;
mmenkecc2298e2015-12-07 18:20:182254 for (size_t i = 0; i < kNumUnreadBodies; ++i) {
[email protected]49639fa2011-12-20 23:22:412255 TestCompletionCallback callback;
[email protected]fc31d6a42010-06-24 18:05:132256
Jeremy Roman0579ed62017-08-29 15:56:192257 auto trans = std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
bnc87dcefc2017-05-25 12:47:582258 session.get());
[email protected]fc31d6a42010-06-24 18:05:132259
tfarina42834112016-09-22 13:38:202260 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012261 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]fc31d6a42010-06-24 18:05:132262
[email protected]58e32bb2013-01-21 18:23:252263 LoadTimingInfo load_timing_info;
2264 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
2265 if (i == 0) {
2266 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
2267 first_socket_log_id = load_timing_info.socket_log_id;
2268 } else {
2269 TestLoadTimingReused(load_timing_info);
2270 EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
2271 }
2272
[email protected]fc31d6a42010-06-24 18:05:132273 const HttpResponseInfo* response = trans->GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182274 ASSERT_TRUE(response);
[email protected]fc31d6a42010-06-24 18:05:132275
mmenkecc2298e2015-12-07 18:20:182276 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502277 response_lines[i] = response->headers->GetStatusLine();
2278
mmenkecc2298e2015-12-07 18:20:182279 // Delete the transaction without reading the response bodies. Then spin
2280 // the message loop, so the response bodies are drained.
2281 trans.reset();
2282 base::RunLoop().RunUntilIdle();
[email protected]fc31d6a42010-06-24 18:05:132283 }
[email protected]0b0bf032010-09-21 18:08:502284
2285 const char* const kStatusLines[] = {
mmenkecc2298e2015-12-07 18:20:182286 "HTTP/1.1 204 No Content",
2287 "HTTP/1.1 205 Reset Content",
2288 "HTTP/1.1 304 Not Modified",
2289 "HTTP/1.1 302 Found",
2290 "HTTP/1.1 302 Found",
2291 "HTTP/1.1 301 Moved Permanently",
2292 "HTTP/1.1 301 Moved Permanently",
2293 "HTTP/1.1 200 Hunky-Dory",
2294 "HTTP/1.1 200 Hunky-Dory",
[email protected]0b0bf032010-09-21 18:08:502295 };
2296
Avi Drissman4365a4782018-12-28 19:26:242297 static_assert(kNumUnreadBodies == base::size(kStatusLines),
mostynb91e0da982015-01-20 19:17:272298 "forgot to update kStatusLines");
[email protected]0b0bf032010-09-21 18:08:502299
2300 for (int i = 0; i < kNumUnreadBodies; ++i)
2301 EXPECT_EQ(kStatusLines[i], response_lines[i]);
2302
[email protected]49639fa2011-12-20 23:22:412303 TestCompletionCallback callback;
bnc691fda62016-08-12 00:43:162304 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202305 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012306 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:162307 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:182308 ASSERT_TRUE(response);
2309 ASSERT_TRUE(response->headers);
[email protected]0b0bf032010-09-21 18:08:502310 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2311 std::string response_data;
bnc691fda62016-08-12 00:43:162312 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:012313 EXPECT_THAT(rv, IsOk());
[email protected]0b0bf032010-09-21 18:08:502314 EXPECT_EQ("hello", response_data);
[email protected]fc31d6a42010-06-24 18:05:132315}
2316
mmenke5f94fda2016-06-02 20:54:132317// Sockets that receive extra data after a response is complete should not be
2318// reused.
bncd16676a2016-07-20 16:23:012319TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData1) {
mmenke5f94fda2016-06-02 20:54:132320 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2321 MockWrite data_writes1[] = {
2322 MockWrite("HEAD / HTTP/1.1\r\n"
2323 "Host: www.borked.com\r\n"
2324 "Connection: keep-alive\r\n\r\n"),
2325 };
2326
2327 MockRead data_reads1[] = {
2328 MockRead("HTTP/1.1 200 OK\r\n"
2329 "Connection: keep-alive\r\n"
2330 "Content-Length: 22\r\n\r\n"
2331 "This server is borked."),
2332 };
2333
2334 MockWrite data_writes2[] = {
2335 MockWrite("GET /foo HTTP/1.1\r\n"
2336 "Host: www.borked.com\r\n"
2337 "Connection: keep-alive\r\n\r\n"),
2338 };
2339
2340 MockRead data_reads2[] = {
2341 MockRead("HTTP/1.1 200 OK\r\n"
2342 "Content-Length: 3\r\n\r\n"
2343 "foo"),
2344 };
Ryan Sleevib8d7ea02018-05-07 20:01:012345 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132346 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012347 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132348 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2349
2350 TestCompletionCallback callback;
2351 HttpRequestInfo request1;
2352 request1.method = "HEAD";
2353 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102354 request1.traffic_annotation =
2355 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132356
bnc87dcefc2017-05-25 12:47:582357 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192358 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202359 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012360 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132361
2362 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2363 ASSERT_TRUE(response1);
2364 ASSERT_TRUE(response1->headers);
2365 EXPECT_EQ(200, response1->headers->response_code());
2366 EXPECT_TRUE(response1->headers->IsKeepAlive());
2367
2368 std::string response_data1;
robpercival214763f2016-07-01 23:27:012369 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132370 EXPECT_EQ("", response_data1);
2371 // Deleting the transaction attempts to release the socket back into the
2372 // socket pool.
2373 trans1.reset();
2374
2375 HttpRequestInfo request2;
2376 request2.method = "GET";
2377 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102378 request2.traffic_annotation =
2379 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132380
bnc87dcefc2017-05-25 12:47:582381 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192382 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202383 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012384 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132385
2386 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2387 ASSERT_TRUE(response2);
2388 ASSERT_TRUE(response2->headers);
2389 EXPECT_EQ(200, response2->headers->response_code());
2390
2391 std::string response_data2;
robpercival214763f2016-07-01 23:27:012392 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132393 EXPECT_EQ("foo", response_data2);
2394}
2395
bncd16676a2016-07-20 16:23:012396TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData2) {
mmenke5f94fda2016-06-02 20:54:132397 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2398 MockWrite data_writes1[] = {
2399 MockWrite("GET / HTTP/1.1\r\n"
2400 "Host: www.borked.com\r\n"
2401 "Connection: keep-alive\r\n\r\n"),
2402 };
2403
2404 MockRead data_reads1[] = {
2405 MockRead("HTTP/1.1 200 OK\r\n"
2406 "Connection: keep-alive\r\n"
2407 "Content-Length: 22\r\n\r\n"
2408 "This server is borked."
2409 "Bonus data!"),
2410 };
2411
2412 MockWrite data_writes2[] = {
2413 MockWrite("GET /foo HTTP/1.1\r\n"
2414 "Host: www.borked.com\r\n"
2415 "Connection: keep-alive\r\n\r\n"),
2416 };
2417
2418 MockRead data_reads2[] = {
2419 MockRead("HTTP/1.1 200 OK\r\n"
2420 "Content-Length: 3\r\n\r\n"
2421 "foo"),
2422 };
Ryan Sleevib8d7ea02018-05-07 20:01:012423 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132424 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012425 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132426 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2427
2428 TestCompletionCallback callback;
2429 HttpRequestInfo request1;
2430 request1.method = "GET";
2431 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102432 request1.traffic_annotation =
2433 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132434
bnc87dcefc2017-05-25 12:47:582435 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192436 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202437 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012438 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132439
2440 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2441 ASSERT_TRUE(response1);
2442 ASSERT_TRUE(response1->headers);
2443 EXPECT_EQ(200, response1->headers->response_code());
2444 EXPECT_TRUE(response1->headers->IsKeepAlive());
2445
2446 std::string response_data1;
robpercival214763f2016-07-01 23:27:012447 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132448 EXPECT_EQ("This server is borked.", response_data1);
2449 // Deleting the transaction attempts to release the socket back into the
2450 // socket pool.
2451 trans1.reset();
2452
2453 HttpRequestInfo request2;
2454 request2.method = "GET";
2455 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102456 request2.traffic_annotation =
2457 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132458
bnc87dcefc2017-05-25 12:47:582459 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192460 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202461 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012462 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132463
2464 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2465 ASSERT_TRUE(response2);
2466 ASSERT_TRUE(response2->headers);
2467 EXPECT_EQ(200, response2->headers->response_code());
2468
2469 std::string response_data2;
robpercival214763f2016-07-01 23:27:012470 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132471 EXPECT_EQ("foo", response_data2);
2472}
2473
bncd16676a2016-07-20 16:23:012474TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData3) {
mmenke5f94fda2016-06-02 20:54:132475 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2476 MockWrite data_writes1[] = {
2477 MockWrite("GET / HTTP/1.1\r\n"
2478 "Host: www.borked.com\r\n"
2479 "Connection: keep-alive\r\n\r\n"),
2480 };
2481
2482 MockRead data_reads1[] = {
2483 MockRead("HTTP/1.1 200 OK\r\n"
2484 "Connection: keep-alive\r\n"
2485 "Transfer-Encoding: chunked\r\n\r\n"),
2486 MockRead("16\r\nThis server is borked.\r\n"),
2487 MockRead("0\r\n\r\nBonus data!"),
2488 };
2489
2490 MockWrite data_writes2[] = {
2491 MockWrite("GET /foo HTTP/1.1\r\n"
2492 "Host: www.borked.com\r\n"
2493 "Connection: keep-alive\r\n\r\n"),
2494 };
2495
2496 MockRead data_reads2[] = {
2497 MockRead("HTTP/1.1 200 OK\r\n"
2498 "Content-Length: 3\r\n\r\n"
2499 "foo"),
2500 };
Ryan Sleevib8d7ea02018-05-07 20:01:012501 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132502 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:012503 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke5f94fda2016-06-02 20:54:132504 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2505
2506 TestCompletionCallback callback;
2507 HttpRequestInfo request1;
2508 request1.method = "GET";
2509 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102510 request1.traffic_annotation =
2511 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132512
bnc87dcefc2017-05-25 12:47:582513 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:192514 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202515 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012516 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132517
2518 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
2519 ASSERT_TRUE(response1);
2520 ASSERT_TRUE(response1->headers);
2521 EXPECT_EQ(200, response1->headers->response_code());
2522 EXPECT_TRUE(response1->headers->IsKeepAlive());
2523
2524 std::string response_data1;
robpercival214763f2016-07-01 23:27:012525 EXPECT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk());
mmenke5f94fda2016-06-02 20:54:132526 EXPECT_EQ("This server is borked.", response_data1);
2527 // Deleting the transaction attempts to release the socket back into the
2528 // socket pool.
2529 trans1.reset();
2530
2531 HttpRequestInfo request2;
2532 request2.method = "GET";
2533 request2.url = GURL("http://www.borked.com/foo");
Ramin Halavatib5e433e62018-02-07 07:41:102534 request2.traffic_annotation =
2535 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132536
bnc87dcefc2017-05-25 12:47:582537 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:192538 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202539 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012540 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132541
2542 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
2543 ASSERT_TRUE(response2);
2544 ASSERT_TRUE(response2->headers);
2545 EXPECT_EQ(200, response2->headers->response_code());
2546
2547 std::string response_data2;
robpercival214763f2016-07-01 23:27:012548 EXPECT_THAT(ReadTransaction(trans2.get(), &response_data2), IsOk());
mmenke5f94fda2016-06-02 20:54:132549 EXPECT_EQ("foo", response_data2);
2550}
2551
2552// This is a little different from the others - it tests the case that the
2553// HttpStreamParser doesn't know if there's extra data on a socket or not when
2554// the HttpNetworkTransaction is torn down, because the response body hasn't
2555// been read from yet, but the request goes through the HttpResponseBodyDrainer.
bncd16676a2016-07-20 16:23:012556TEST_F(HttpNetworkTransactionTest, KeepAliveWithUnusedData4) {
mmenke5f94fda2016-06-02 20:54:132557 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2558 MockWrite data_writes1[] = {
2559 MockWrite("GET / HTTP/1.1\r\n"
2560 "Host: www.borked.com\r\n"
2561 "Connection: keep-alive\r\n\r\n"),
2562 };
2563
2564 MockRead data_reads1[] = {
2565 MockRead("HTTP/1.1 200 OK\r\n"
2566 "Connection: keep-alive\r\n"
2567 "Transfer-Encoding: chunked\r\n\r\n"),
2568 MockRead("16\r\nThis server is borked.\r\n"),
2569 MockRead("0\r\n\r\nBonus data!"),
2570 };
Ryan Sleevib8d7ea02018-05-07 20:01:012571 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke5f94fda2016-06-02 20:54:132572 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2573
2574 TestCompletionCallback callback;
2575 HttpRequestInfo request1;
2576 request1.method = "GET";
2577 request1.url = GURL("http://www.borked.com/");
Ramin Halavatib5e433e62018-02-07 07:41:102578 request1.traffic_annotation =
2579 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke5f94fda2016-06-02 20:54:132580
bnc87dcefc2017-05-25 12:47:582581 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:192582 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
bnc87dcefc2017-05-25 12:47:582583 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012584 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke5f94fda2016-06-02 20:54:132585
bnc87dcefc2017-05-25 12:47:582586 const HttpResponseInfo* response1 = trans->GetResponseInfo();
mmenke5f94fda2016-06-02 20:54:132587 ASSERT_TRUE(response1);
2588 ASSERT_TRUE(response1->headers);
2589 EXPECT_EQ(200, response1->headers->response_code());
2590 EXPECT_TRUE(response1->headers->IsKeepAlive());
2591
2592 // Deleting the transaction creates an HttpResponseBodyDrainer to read the
2593 // response body.
bnc87dcefc2017-05-25 12:47:582594 trans.reset();
mmenke5f94fda2016-06-02 20:54:132595
2596 // Let the HttpResponseBodyDrainer drain the socket. It should determine the
2597 // socket can't be reused, rather than returning it to the socket pool.
2598 base::RunLoop().RunUntilIdle();
2599
2600 // There should be no idle sockets in the pool.
2601 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
2602}
2603
[email protected]038e9a32008-10-08 22:40:162604// Test the request-challenge-retry sequence for basic auth.
2605// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012606TEST_F(HttpNetworkTransactionTest, BasicAuth) {
[email protected]1c773ea12009-04-28 19:58:422607 HttpRequestInfo request;
[email protected]038e9a32008-10-08 22:40:162608 request.method = "GET";
bncce36dca22015-04-21 22:11:232609 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102610 request.traffic_annotation =
2611 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]038e9a32008-10-08 22:40:162612
vishal.b62985ca92015-04-17 08:45:512613 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:072614 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092615 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162616 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272617
[email protected]f9ee6b52008-11-08 06:46:232618 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:232619 MockWrite(
2620 "GET / HTTP/1.1\r\n"
2621 "Host: www.example.org\r\n"
2622 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:232623 };
2624
[email protected]038e9a32008-10-08 22:40:162625 MockRead data_reads1[] = {
2626 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2627 // Give a couple authenticate options (only the middle one is actually
2628 // supported).
[email protected]22927ad2009-09-21 19:56:192629 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:162630 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2631 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2632 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2633 // Large content-length -- won't matter, as connection will be reset.
2634 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062635 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:162636 };
2637
2638 // After calling trans->RestartWithAuth(), this is the request we should
2639 // be issuing -- the final header line contains the credentials.
2640 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:232641 MockWrite(
2642 "GET / HTTP/1.1\r\n"
2643 "Host: www.example.org\r\n"
2644 "Connection: keep-alive\r\n"
2645 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:162646 };
2647
2648 // Lastly, the server responds with the actual content.
2649 MockRead data_reads2[] = {
2650 MockRead("HTTP/1.0 200 OK\r\n"),
2651 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2652 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062653 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:162654 };
2655
Ryan Sleevib8d7ea02018-05-07 20:01:012656 StaticSocketDataProvider data1(data_reads1, data_writes1);
2657 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:072658 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2659 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]038e9a32008-10-08 22:40:162660
[email protected]49639fa2011-12-20 23:22:412661 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:162662
tfarina42834112016-09-22 13:38:202663 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012664 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162665
2666 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:012667 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162668
[email protected]58e32bb2013-01-21 18:23:252669 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162670 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
[email protected]58e32bb2013-01-21 18:23:252671 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2672
Ryan Sleevib8d7ea02018-05-07 20:01:012673 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162674 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012675 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162676 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192677
bnc691fda62016-08-12 00:43:162678 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522679 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:582680 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]038e9a32008-10-08 22:40:162681
[email protected]49639fa2011-12-20 23:22:412682 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:162683
bnc691fda62016-08-12 00:43:162684 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:012685 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:162686
2687 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:012688 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:162689
[email protected]58e32bb2013-01-21 18:23:252690 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162691 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
[email protected]58e32bb2013-01-21 18:23:252692 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2693 // The load timing after restart should have a new socket ID, and times after
2694 // those of the first load timing.
2695 EXPECT_LE(load_timing_info1.receive_headers_end,
2696 load_timing_info2.connect_timing.connect_start);
2697 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2698
Ryan Sleevib8d7ea02018-05-07 20:01:012699 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162700 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012701 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162702 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192703
bnc691fda62016-08-12 00:43:162704 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522705 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:582706 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]038e9a32008-10-08 22:40:162707 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:162708}
2709
ttuttled9dbc652015-09-29 20:00:592710// Test the request-challenge-retry sequence for basic auth.
2711// (basic auth is the easiest to mock, because it has no randomness).
bncd16676a2016-07-20 16:23:012712TEST_F(HttpNetworkTransactionTest, BasicAuthWithAddressChange) {
ttuttled9dbc652015-09-29 20:00:592713 HttpRequestInfo request;
2714 request.method = "GET";
2715 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102716 request.traffic_annotation =
2717 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttled9dbc652015-09-29 20:00:592718
2719 TestNetLog log;
2720 MockHostResolver* resolver = new MockHostResolver();
2721 session_deps_.net_log = &log;
2722 session_deps_.host_resolver.reset(resolver);
danakj1fd259a02016-04-16 03:17:092723 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
bnc691fda62016-08-12 00:43:162724 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttled9dbc652015-09-29 20:00:592725
2726 resolver->rules()->ClearRules();
2727 resolver->rules()->AddRule("www.example.org", "127.0.0.1");
2728
2729 MockWrite data_writes1[] = {
2730 MockWrite("GET / HTTP/1.1\r\n"
2731 "Host: www.example.org\r\n"
2732 "Connection: keep-alive\r\n\r\n"),
2733 };
2734
2735 MockRead data_reads1[] = {
2736 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2737 // Give a couple authenticate options (only the middle one is actually
2738 // supported).
2739 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2740 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2741 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2742 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2743 // Large content-length -- won't matter, as connection will be reset.
2744 MockRead("Content-Length: 10000\r\n\r\n"),
2745 MockRead(SYNCHRONOUS, ERR_FAILED),
2746 };
2747
2748 // After calling trans->RestartWithAuth(), this is the request we should
2749 // be issuing -- the final header line contains the credentials.
2750 MockWrite data_writes2[] = {
2751 MockWrite("GET / HTTP/1.1\r\n"
2752 "Host: www.example.org\r\n"
2753 "Connection: keep-alive\r\n"
2754 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2755 };
2756
2757 // Lastly, the server responds with the actual content.
2758 MockRead data_reads2[] = {
2759 MockRead("HTTP/1.0 200 OK\r\n"),
2760 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2761 MockRead("Content-Length: 100\r\n\r\n"), MockRead(SYNCHRONOUS, OK),
2762 };
2763
Ryan Sleevib8d7ea02018-05-07 20:01:012764 StaticSocketDataProvider data1(data_reads1, data_writes1);
2765 StaticSocketDataProvider data2(data_reads2, data_writes2);
ttuttled9dbc652015-09-29 20:00:592766 session_deps_.socket_factory->AddSocketDataProvider(&data1);
2767 session_deps_.socket_factory->AddSocketDataProvider(&data2);
2768
2769 TestCompletionCallback callback1;
2770
bnc691fda62016-08-12 00:43:162771 EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(),
tfarina42834112016-09-22 13:38:202772 NetLogWithSource())));
ttuttled9dbc652015-09-29 20:00:592773
2774 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162775 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
ttuttled9dbc652015-09-29 20:00:592776 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
2777
Ryan Sleevib8d7ea02018-05-07 20:01:012778 int64_t writes_size1 = CountWriteBytes(data_writes1);
bnc691fda62016-08-12 00:43:162779 EXPECT_EQ(writes_size1, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012780 int64_t reads_size1 = CountReadBytes(data_reads1);
bnc691fda62016-08-12 00:43:162781 EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592782
bnc691fda62016-08-12 00:43:162783 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592784 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:582785 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
ttuttled9dbc652015-09-29 20:00:592786
2787 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:162788 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592789 ASSERT_FALSE(endpoint.address().empty());
2790 EXPECT_EQ("127.0.0.1:80", endpoint.ToString());
2791
2792 resolver->rules()->ClearRules();
2793 resolver->rules()->AddRule("www.example.org", "127.0.0.2");
2794
2795 TestCompletionCallback callback2;
2796
bnc691fda62016-08-12 00:43:162797 EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth(
ttuttled9dbc652015-09-29 20:00:592798 AuthCredentials(kFoo, kBar), callback2.callback())));
2799
2800 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:162801 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
ttuttled9dbc652015-09-29 20:00:592802 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
2803 // The load timing after restart should have a new socket ID, and times after
2804 // those of the first load timing.
2805 EXPECT_LE(load_timing_info1.receive_headers_end,
2806 load_timing_info2.connect_timing.connect_start);
2807 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
2808
Ryan Sleevib8d7ea02018-05-07 20:01:012809 int64_t writes_size2 = CountWriteBytes(data_writes2);
bnc691fda62016-08-12 00:43:162810 EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012811 int64_t reads_size2 = CountReadBytes(data_reads2);
bnc691fda62016-08-12 00:43:162812 EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes());
ttuttled9dbc652015-09-29 20:00:592813
bnc691fda62016-08-12 00:43:162814 response = trans.GetResponseInfo();
ttuttled9dbc652015-09-29 20:00:592815 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:582816 EXPECT_FALSE(response->auth_challenge.has_value());
ttuttled9dbc652015-09-29 20:00:592817 EXPECT_EQ(100, response->headers->GetContentLength());
2818
bnc691fda62016-08-12 00:43:162819 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:592820 ASSERT_FALSE(endpoint.address().empty());
2821 EXPECT_EQ("127.0.0.2:80", endpoint.ToString());
2822}
2823
David Benjamin83ddfb32018-03-30 01:07:522824// Test that, if the server requests auth indefinitely, HttpNetworkTransaction
2825// will eventually give up.
2826TEST_F(HttpNetworkTransactionTest, BasicAuthForever) {
2827 HttpRequestInfo request;
2828 request.method = "GET";
2829 request.url = GURL("http://www.example.org/");
2830 request.traffic_annotation =
2831 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2832
2833 TestNetLog log;
2834 session_deps_.net_log = &log;
2835 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
2836 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
2837
2838 MockWrite data_writes[] = {
2839 MockWrite("GET / HTTP/1.1\r\n"
2840 "Host: www.example.org\r\n"
2841 "Connection: keep-alive\r\n\r\n"),
2842 };
2843
2844 MockRead data_reads[] = {
2845 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2846 // Give a couple authenticate options (only the middle one is actually
2847 // supported).
2848 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
2849 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2850 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
2851 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2852 // Large content-length -- won't matter, as connection will be reset.
2853 MockRead("Content-Length: 10000\r\n\r\n"),
2854 MockRead(SYNCHRONOUS, ERR_FAILED),
2855 };
2856
2857 // After calling trans->RestartWithAuth(), this is the request we should
2858 // be issuing -- the final header line contains the credentials.
2859 MockWrite data_writes_restart[] = {
2860 MockWrite("GET / HTTP/1.1\r\n"
2861 "Host: www.example.org\r\n"
2862 "Connection: keep-alive\r\n"
2863 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2864 };
2865
Ryan Sleevib8d7ea02018-05-07 20:01:012866 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin83ddfb32018-03-30 01:07:522867 session_deps_.socket_factory->AddSocketDataProvider(&data);
2868
2869 TestCompletionCallback callback;
2870 int rv = callback.GetResult(
2871 trans.Start(&request, callback.callback(), NetLogWithSource()));
2872
2873 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_restarts;
2874 for (int i = 0; i < 32; i++) {
2875 // Check the previous response was a 401.
2876 EXPECT_THAT(rv, IsOk());
2877 const HttpResponseInfo* response = trans.GetResponseInfo();
2878 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:582879 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
David Benjamin83ddfb32018-03-30 01:07:522880
2881 data_restarts.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:012882 data_reads, data_writes_restart));
David Benjamin83ddfb32018-03-30 01:07:522883 session_deps_.socket_factory->AddSocketDataProvider(
2884 data_restarts.back().get());
2885 rv = callback.GetResult(trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
2886 callback.callback()));
2887 }
2888
2889 // After too many tries, the transaction should have given up.
2890 EXPECT_THAT(rv, IsError(ERR_TOO_MANY_RETRIES));
2891}
2892
bncd16676a2016-07-20 16:23:012893TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
[email protected]861fcd52009-08-26 02:33:462894 HttpRequestInfo request;
2895 request.method = "GET";
bncce36dca22015-04-21 22:11:232896 request.url = GURL("http://www.example.org/");
ttuttle859dc7a2015-04-23 19:42:292897 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:102898 request.traffic_annotation =
2899 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]861fcd52009-08-26 02:33:462900
danakj1fd259a02016-04-16 03:17:092901 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:162902 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:272903
[email protected]861fcd52009-08-26 02:33:462904 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:232905 MockWrite(
2906 "GET / HTTP/1.1\r\n"
2907 "Host: www.example.org\r\n"
2908 "Connection: keep-alive\r\n\r\n"),
[email protected]861fcd52009-08-26 02:33:462909 };
2910
2911 MockRead data_reads[] = {
2912 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
2913 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2914 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
2915 // Large content-length -- won't matter, as connection will be reset.
2916 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:062917 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]861fcd52009-08-26 02:33:462918 };
2919
Ryan Sleevib8d7ea02018-05-07 20:01:012920 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:072921 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]49639fa2011-12-20 23:22:412922 TestCompletionCallback callback;
[email protected]861fcd52009-08-26 02:33:462923
tfarina42834112016-09-22 13:38:202924 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012925 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]861fcd52009-08-26 02:33:462926
2927 rv = callback.WaitForResult();
2928 EXPECT_EQ(0, rv);
2929
Ryan Sleevib8d7ea02018-05-07 20:01:012930 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:162931 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:012932 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:162933 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
[email protected]b8015c42013-12-24 15:18:192934
bnc691fda62016-08-12 00:43:162935 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:522936 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:582937 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]861fcd52009-08-26 02:33:462938}
2939
[email protected]2d2697f92009-02-18 21:00:322940// Test the request-challenge-retry sequence for basic auth, over a keep-alive
2941// connection.
bncd16676a2016-07-20 16:23:012942TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
mmenkecc2298e2015-12-07 18:20:182943 // On the second pass, the body read of the auth challenge is synchronous, so
2944 // IsConnectedAndIdle returns false. The socket should still be drained and
2945 // reused. See http://crbug.com/544255.
2946 for (int i = 0; i < 2; ++i) {
2947 HttpRequestInfo request;
2948 request.method = "GET";
2949 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:102950 request.traffic_annotation =
2951 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:322952
mmenkecc2298e2015-12-07 18:20:182953 TestNetLog log;
2954 session_deps_.net_log = &log;
danakj1fd259a02016-04-16 03:17:092955 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:272956
mmenkecc2298e2015-12-07 18:20:182957 MockWrite data_writes[] = {
2958 MockWrite(ASYNC, 0,
2959 "GET / HTTP/1.1\r\n"
2960 "Host: www.example.org\r\n"
2961 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:322962
bnc691fda62016-08-12 00:43:162963 // After calling trans.RestartWithAuth(), this is the request we should
mmenkecc2298e2015-12-07 18:20:182964 // be issuing -- the final header line contains the credentials.
2965 MockWrite(ASYNC, 6,
2966 "GET / HTTP/1.1\r\n"
2967 "Host: www.example.org\r\n"
2968 "Connection: keep-alive\r\n"
2969 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
2970 };
[email protected]2d2697f92009-02-18 21:00:322971
mmenkecc2298e2015-12-07 18:20:182972 MockRead data_reads[] = {
2973 MockRead(ASYNC, 1, "HTTP/1.1 401 Unauthorized\r\n"),
2974 MockRead(ASYNC, 2, "WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
2975 MockRead(ASYNC, 3, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2976 MockRead(ASYNC, 4, "Content-Length: 14\r\n\r\n"),
2977 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 5, "Unauthorized\r\n"),
[email protected]2d2697f92009-02-18 21:00:322978
mmenkecc2298e2015-12-07 18:20:182979 // Lastly, the server responds with the actual content.
2980 MockRead(ASYNC, 7, "HTTP/1.1 200 OK\r\n"),
2981 MockRead(ASYNC, 8, "Content-Type: text/html; charset=iso-8859-1\r\n"),
2982 MockRead(ASYNC, 9, "Content-Length: 5\r\n\r\n"),
2983 MockRead(ASYNC, 10, "Hello"),
2984 };
[email protected]2d2697f92009-02-18 21:00:322985
Ryan Sleevib8d7ea02018-05-07 20:01:012986 SequencedSocketData data(data_reads, data_writes);
mmenkecc2298e2015-12-07 18:20:182987 data.set_busy_before_sync_reads(true);
2988 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]2d0a4f92011-05-05 16:38:462989
mmenkecc2298e2015-12-07 18:20:182990 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:322991
bnc691fda62016-08-12 00:43:162992 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:202993 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:012994 ASSERT_THAT(callback1.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:322995
mmenkecc2298e2015-12-07 18:20:182996 LoadTimingInfo load_timing_info1;
bnc691fda62016-08-12 00:43:162997 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1));
mmenkecc2298e2015-12-07 18:20:182998 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
[email protected]2d2697f92009-02-18 21:00:322999
bnc691fda62016-08-12 00:43:163000 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:183001 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583002 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]2d2697f92009-02-18 21:00:323003
mmenkecc2298e2015-12-07 18:20:183004 TestCompletionCallback callback2;
[email protected]58e32bb2013-01-21 18:23:253005
bnc691fda62016-08-12 00:43:163006 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
3007 callback2.callback());
robpercival214763f2016-07-01 23:27:013008 ASSERT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323009
mmenkecc2298e2015-12-07 18:20:183010 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:163011 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2));
mmenkecc2298e2015-12-07 18:20:183012 TestLoadTimingReused(load_timing_info2);
3013 // The load timing after restart should have the same socket ID, and times
3014 // those of the first load timing.
3015 EXPECT_LE(load_timing_info1.receive_headers_end,
3016 load_timing_info2.send_start);
3017 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]2d2697f92009-02-18 21:00:323018
bnc691fda62016-08-12 00:43:163019 response = trans.GetResponseInfo();
mmenkecc2298e2015-12-07 18:20:183020 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583021 EXPECT_FALSE(response->auth_challenge.has_value());
mmenkecc2298e2015-12-07 18:20:183022 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323023
mmenkecc2298e2015-12-07 18:20:183024 std::string response_data;
bnc691fda62016-08-12 00:43:163025 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]2d2697f92009-02-18 21:00:323026
Ryan Sleevib8d7ea02018-05-07 20:01:013027 int64_t writes_size = CountWriteBytes(data_writes);
bnc691fda62016-08-12 00:43:163028 EXPECT_EQ(writes_size, trans.GetTotalSentBytes());
Ryan Sleevib8d7ea02018-05-07 20:01:013029 int64_t reads_size = CountReadBytes(data_reads);
bnc691fda62016-08-12 00:43:163030 EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes());
mmenkecc2298e2015-12-07 18:20:183031 }
[email protected]2d2697f92009-02-18 21:00:323032}
3033
3034// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3035// connection and with no response body to drain.
bncd16676a2016-07-20 16:23:013036TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
[email protected]1c773ea12009-04-28 19:58:423037 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323038 request.method = "GET";
bncce36dca22015-04-21 22:11:233039 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103040 request.traffic_annotation =
3041 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323042
danakj1fd259a02016-04-16 03:17:093043 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273044
[email protected]2d2697f92009-02-18 21:00:323045 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:163046 MockWrite("GET / HTTP/1.1\r\n"
3047 "Host: www.example.org\r\n"
3048 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323049
bnc691fda62016-08-12 00:43:163050 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233051 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163052 MockWrite("GET / HTTP/1.1\r\n"
3053 "Host: www.example.org\r\n"
3054 "Connection: keep-alive\r\n"
3055 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323056 };
3057
[email protected]2d2697f92009-02-18 21:00:323058 MockRead data_reads1[] = {
3059 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3060 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
[email protected]11203f012009-11-12 23:02:313061 MockRead("Content-Length: 0\r\n\r\n"), // No response body.
[email protected]2d2697f92009-02-18 21:00:323062
3063 // Lastly, the server responds with the actual content.
3064 MockRead("HTTP/1.1 200 OK\r\n"),
3065 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503066 MockRead("Content-Length: 5\r\n\r\n"),
3067 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323068 };
3069
[email protected]2d0a4f92011-05-05 16:38:463070 // An incorrect reconnect would cause this to be read.
3071 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063072 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463073 };
3074
Ryan Sleevib8d7ea02018-05-07 20:01:013075 StaticSocketDataProvider data1(data_reads1, data_writes1);
3076 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073077 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3078 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323079
[email protected]49639fa2011-12-20 23:22:413080 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323081
bnc691fda62016-08-12 00:43:163082 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203083 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013084 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323085
3086 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013087 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323088
bnc691fda62016-08-12 00:43:163089 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523090 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583091 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]2d2697f92009-02-18 21:00:323092
[email protected]49639fa2011-12-20 23:22:413093 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323094
bnc691fda62016-08-12 00:43:163095 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013096 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323097
3098 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013099 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323100
bnc691fda62016-08-12 00:43:163101 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523102 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583103 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]0b0bf032010-09-21 18:08:503104 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323105}
3106
3107// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3108// connection and with a large response body to drain.
bncd16676a2016-07-20 16:23:013109TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
[email protected]1c773ea12009-04-28 19:58:423110 HttpRequestInfo request;
[email protected]2d2697f92009-02-18 21:00:323111 request.method = "GET";
bncce36dca22015-04-21 22:11:233112 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103113 request.traffic_annotation =
3114 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d2697f92009-02-18 21:00:323115
danakj1fd259a02016-04-16 03:17:093116 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273117
[email protected]2d2697f92009-02-18 21:00:323118 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:163119 MockWrite("GET / HTTP/1.1\r\n"
3120 "Host: www.example.org\r\n"
3121 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323122
bnc691fda62016-08-12 00:43:163123 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:233124 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:163125 MockWrite("GET / HTTP/1.1\r\n"
3126 "Host: www.example.org\r\n"
3127 "Connection: keep-alive\r\n"
3128 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323129 };
3130
3131 // Respond with 5 kb of response body.
3132 std::string large_body_string("Unauthorized");
3133 large_body_string.append(5 * 1024, ' ');
3134 large_body_string.append("\r\n");
3135
3136 MockRead data_reads1[] = {
3137 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3138 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3139 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3140 // 5134 = 12 + 5 * 1024 + 2
3141 MockRead("Content-Length: 5134\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:063142 MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
[email protected]2d2697f92009-02-18 21:00:323143
3144 // Lastly, the server responds with the actual content.
3145 MockRead("HTTP/1.1 200 OK\r\n"),
3146 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503147 MockRead("Content-Length: 5\r\n\r\n"),
3148 MockRead("hello"),
[email protected]2d2697f92009-02-18 21:00:323149 };
3150
[email protected]2d0a4f92011-05-05 16:38:463151 // An incorrect reconnect would cause this to be read.
3152 MockRead data_reads2[] = {
[email protected]8ddf8322012-02-23 18:08:063153 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]2d0a4f92011-05-05 16:38:463154 };
3155
Ryan Sleevib8d7ea02018-05-07 20:01:013156 StaticSocketDataProvider data1(data_reads1, data_writes1);
3157 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:073158 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3159 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d2697f92009-02-18 21:00:323160
[email protected]49639fa2011-12-20 23:22:413161 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323162
bnc691fda62016-08-12 00:43:163163 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203164 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013165 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323166
3167 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013168 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323169
bnc691fda62016-08-12 00:43:163170 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523171 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583172 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]2d2697f92009-02-18 21:00:323173
[email protected]49639fa2011-12-20 23:22:413174 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323175
bnc691fda62016-08-12 00:43:163176 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013177 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d2697f92009-02-18 21:00:323178
3179 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013180 EXPECT_THAT(rv, IsOk());
[email protected]2d2697f92009-02-18 21:00:323181
bnc691fda62016-08-12 00:43:163182 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523183 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583184 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]0b0bf032010-09-21 18:08:503185 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]2d2697f92009-02-18 21:00:323186}
3187
3188// Test the request-challenge-retry sequence for basic auth, over a keep-alive
[email protected]11203f012009-11-12 23:02:313189// connection, but the server gets impatient and closes the connection.
bncd16676a2016-07-20 16:23:013190TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
[email protected]11203f012009-11-12 23:02:313191 HttpRequestInfo request;
3192 request.method = "GET";
bncce36dca22015-04-21 22:11:233193 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103194 request.traffic_annotation =
3195 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]11203f012009-11-12 23:02:313196
danakj1fd259a02016-04-16 03:17:093197 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273198
[email protected]11203f012009-11-12 23:02:313199 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:233200 MockWrite(
3201 "GET / HTTP/1.1\r\n"
3202 "Host: www.example.org\r\n"
3203 "Connection: keep-alive\r\n\r\n"),
3204 // This simulates the seemingly successful write to a closed connection
3205 // if the bug is not fixed.
3206 MockWrite(
3207 "GET / HTTP/1.1\r\n"
3208 "Host: www.example.org\r\n"
3209 "Connection: keep-alive\r\n"
3210 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313211 };
3212
3213 MockRead data_reads1[] = {
3214 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
3215 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3216 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3217 MockRead("Content-Length: 14\r\n\r\n"),
3218 // Tell MockTCPClientSocket to simulate the server closing the connection.
[email protected]8ddf8322012-02-23 18:08:063219 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
[email protected]11203f012009-11-12 23:02:313220 MockRead("Unauthorized\r\n"),
[email protected]8ddf8322012-02-23 18:08:063221 MockRead(SYNCHRONOUS, OK), // The server closes the connection.
[email protected]11203f012009-11-12 23:02:313222 };
3223
bnc691fda62016-08-12 00:43:163224 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]11203f012009-11-12 23:02:313225 // be issuing -- the final header line contains the credentials.
3226 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233227 MockWrite(
3228 "GET / HTTP/1.1\r\n"
3229 "Host: www.example.org\r\n"
3230 "Connection: keep-alive\r\n"
3231 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]11203f012009-11-12 23:02:313232 };
3233
3234 // Lastly, the server responds with the actual content.
3235 MockRead data_reads2[] = {
3236 MockRead("HTTP/1.1 200 OK\r\n"),
3237 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
[email protected]0b0bf032010-09-21 18:08:503238 MockRead("Content-Length: 5\r\n\r\n"),
3239 MockRead("hello"),
[email protected]11203f012009-11-12 23:02:313240 };
3241
Ryan Sleevib8d7ea02018-05-07 20:01:013242 StaticSocketDataProvider data1(data_reads1, data_writes1);
3243 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:073244 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3245 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]11203f012009-11-12 23:02:313246
[email protected]49639fa2011-12-20 23:22:413247 TestCompletionCallback callback1;
[email protected]11203f012009-11-12 23:02:313248
bnc691fda62016-08-12 00:43:163249 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:203250 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013251 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313252
3253 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013254 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313255
bnc691fda62016-08-12 00:43:163256 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523257 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583258 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]11203f012009-11-12 23:02:313259
[email protected]49639fa2011-12-20 23:22:413260 TestCompletionCallback callback2;
[email protected]11203f012009-11-12 23:02:313261
bnc691fda62016-08-12 00:43:163262 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013263 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]11203f012009-11-12 23:02:313264
3265 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013266 EXPECT_THAT(rv, IsOk());
[email protected]11203f012009-11-12 23:02:313267
bnc691fda62016-08-12 00:43:163268 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:523269 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:583270 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]0b0bf032010-09-21 18:08:503271 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]11203f012009-11-12 23:02:313272}
3273
[email protected]394816e92010-08-03 07:38:593274// Test the request-challenge-retry sequence for basic auth, over a connection
3275// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013276TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp10) {
ttuttle34f63b52015-03-05 04:33:013277 HttpRequestInfo request;
3278 request.method = "GET";
bncce36dca22015-04-21 22:11:233279 request.url = GURL("https://www.example.org/");
ttuttle34f63b52015-03-05 04:33:013280 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293281 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103282 request.traffic_annotation =
3283 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013284
3285 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593286 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493287 ProxyResolutionService::CreateFixedFromPacResult(
3288 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513289 BoundTestNetLog log;
ttuttle34f63b52015-03-05 04:33:013290 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093291 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013292
3293 // Since we have proxy, should try to establish tunnel.
3294 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543295 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173296 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543297 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013298 };
3299
mmenkee71e15332015-10-07 16:39:543300 // The proxy responds to the connect with a 407, using a non-persistent
ttuttle34f63b52015-03-05 04:33:013301 // connection.
3302 MockRead data_reads1[] = {
3303 // No credentials.
3304 MockRead("HTTP/1.0 407 Proxy Authentication Required\r\n"),
3305 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
mmenkee71e15332015-10-07 16:39:543306 };
ttuttle34f63b52015-03-05 04:33:013307
mmenkee71e15332015-10-07 16:39:543308 // Since the first connection couldn't be reused, need to establish another
3309 // once given credentials.
3310 MockWrite data_writes2[] = {
3311 // After calling trans->RestartWithAuth(), this is the request we should
3312 // be issuing -- the final header line contains the credentials.
3313 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173314 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543315 "Proxy-Connection: keep-alive\r\n"
3316 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3317
3318 MockWrite("GET / HTTP/1.1\r\n"
3319 "Host: www.example.org\r\n"
3320 "Connection: keep-alive\r\n\r\n"),
3321 };
3322
3323 MockRead data_reads2[] = {
ttuttle34f63b52015-03-05 04:33:013324 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
3325
3326 MockRead("HTTP/1.1 200 OK\r\n"),
3327 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3328 MockRead("Content-Length: 5\r\n\r\n"),
3329 MockRead(SYNCHRONOUS, "hello"),
3330 };
3331
Ryan Sleevib8d7ea02018-05-07 20:01:013332 StaticSocketDataProvider data1(data_reads1, data_writes1);
ttuttle34f63b52015-03-05 04:33:013333 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013334 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543335 session_deps_.socket_factory->AddSocketDataProvider(&data2);
ttuttle34f63b52015-03-05 04:33:013336 SSLSocketDataProvider ssl(ASYNC, OK);
3337 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3338
3339 TestCompletionCallback callback1;
3340
bnc87dcefc2017-05-25 12:47:583341 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193342 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013343
3344 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013345 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013346
3347 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013348 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463349 TestNetLogEntry::List entries;
ttuttle34f63b52015-03-05 04:33:013350 log.GetEntries(&entries);
3351 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003352 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3353 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013354 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003355 entries, pos,
3356 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3357 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013358
3359 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523360 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013361 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523362 ASSERT_TRUE(response->headers);
ttuttle34f63b52015-03-05 04:33:013363 EXPECT_EQ(407, response->headers->response_code());
3364 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583365 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
ttuttle34f63b52015-03-05 04:33:013366
3367 LoadTimingInfo load_timing_info;
3368 // CONNECT requests and responses are handled at the connect job level, so
3369 // the transaction does not yet have a connection.
3370 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3371
3372 TestCompletionCallback callback2;
3373
3374 rv =
3375 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013376 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle34f63b52015-03-05 04:33:013377
3378 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013379 EXPECT_THAT(rv, IsOk());
ttuttle34f63b52015-03-05 04:33:013380
3381 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523382 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013383
3384 EXPECT_TRUE(response->headers->IsKeepAlive());
3385 EXPECT_EQ(200, response->headers->response_code());
3386 EXPECT_EQ(5, response->headers->GetContentLength());
3387 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3388
3389 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:583390 EXPECT_FALSE(response->auth_challenge.has_value());
ttuttle34f63b52015-03-05 04:33:013391
3392 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3393 TestLoadTimingNotReusedWithPac(load_timing_info,
3394 CONNECT_TIMING_HAS_SSL_TIMES);
3395
3396 trans.reset();
3397 session->CloseAllConnections();
3398}
3399
3400// Test the request-challenge-retry sequence for basic auth, over a connection
3401// that requires a restart when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013402TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAliveHttp11) {
[email protected]394816e92010-08-03 07:38:593403 HttpRequestInfo request;
3404 request.method = "GET";
bncce36dca22015-04-21 22:11:233405 request.url = GURL("https://www.example.org/");
[email protected]394816e92010-08-03 07:38:593406 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293407 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103408 request.traffic_annotation =
3409 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]394816e92010-08-03 07:38:593410
[email protected]cb9bf6ca2011-01-28 13:15:273411 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593412 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493413 ProxyResolutionService::CreateFixedFromPacResult(
3414 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513415 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073416 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093417 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:273418
[email protected]394816e92010-08-03 07:38:593419 // Since we have proxy, should try to establish tunnel.
3420 MockWrite data_writes1[] = {
mmenkee71e15332015-10-07 16:39:543421 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173422 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543423 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenkee0b5c882015-08-26 20:29:113424 };
3425
mmenkee71e15332015-10-07 16:39:543426 // The proxy responds to the connect with a 407, using a non-persistent
mmenke0fd148d2015-09-30 23:00:083427 // connection.
3428 MockRead data_reads1[] = {
mmenkee71e15332015-10-07 16:39:543429 // No credentials.
3430 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3431 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3432 MockRead("Proxy-Connection: close\r\n\r\n"),
3433 };
mmenkee0b5c882015-08-26 20:29:113434
mmenkee71e15332015-10-07 16:39:543435 MockWrite data_writes2[] = {
3436 // After calling trans->RestartWithAuth(), this is the request we should
3437 // be issuing -- the final header line contains the credentials.
3438 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173439 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543440 "Proxy-Connection: keep-alive\r\n"
3441 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
mmenke0fd148d2015-09-30 23:00:083442
mmenkee71e15332015-10-07 16:39:543443 MockWrite("GET / HTTP/1.1\r\n"
3444 "Host: www.example.org\r\n"
3445 "Connection: keep-alive\r\n\r\n"),
3446 };
3447
3448 MockRead data_reads2[] = {
3449 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3450
3451 MockRead("HTTP/1.1 200 OK\r\n"),
3452 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3453 MockRead("Content-Length: 5\r\n\r\n"),
3454 MockRead(SYNCHRONOUS, "hello"),
[email protected]394816e92010-08-03 07:38:593455 };
3456
Ryan Sleevib8d7ea02018-05-07 20:01:013457 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:073458 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013459 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543460 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8ddf8322012-02-23 18:08:063461 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:073462 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]394816e92010-08-03 07:38:593463
[email protected]49639fa2011-12-20 23:22:413464 TestCompletionCallback callback1;
[email protected]394816e92010-08-03 07:38:593465
bnc87dcefc2017-05-25 12:47:583466 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193467 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:503468
[email protected]49639fa2011-12-20 23:22:413469 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013470 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593471
3472 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:013473 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:463474 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403475 log.GetEntries(&entries);
[email protected]394816e92010-08-03 07:38:593476 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003477 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3478 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593479 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403480 entries, pos,
mikecirone8b85c432016-09-08 19:11:003481 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3482 NetLogEventPhase::NONE);
[email protected]394816e92010-08-03 07:38:593483
3484 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523485 ASSERT_TRUE(response);
ttuttle34f63b52015-03-05 04:33:013486 EXPECT_FALSE(response->headers->IsKeepAlive());
wezca1070932016-05-26 20:30:523487 ASSERT_TRUE(response->headers);
[email protected]394816e92010-08-03 07:38:593488 EXPECT_EQ(407, response->headers->response_code());
3489 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583490 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
[email protected]394816e92010-08-03 07:38:593491
[email protected]029c83b62013-01-24 05:28:203492 LoadTimingInfo load_timing_info;
3493 // CONNECT requests and responses are handled at the connect job level, so
3494 // the transaction does not yet have a connection.
3495 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3496
[email protected]49639fa2011-12-20 23:22:413497 TestCompletionCallback callback2;
[email protected]394816e92010-08-03 07:38:593498
[email protected]49639fa2011-12-20 23:22:413499 rv = trans->RestartWithAuth(
3500 AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013501 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]394816e92010-08-03 07:38:593502
3503 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:013504 EXPECT_THAT(rv, IsOk());
[email protected]394816e92010-08-03 07:38:593505
3506 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:523507 ASSERT_TRUE(response);
[email protected]394816e92010-08-03 07:38:593508
3509 EXPECT_TRUE(response->headers->IsKeepAlive());
3510 EXPECT_EQ(200, response->headers->response_code());
[email protected]0b0bf032010-09-21 18:08:503511 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]394816e92010-08-03 07:38:593512 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
3513
3514 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:583515 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]0b0bf032010-09-21 18:08:503516
[email protected]029c83b62013-01-24 05:28:203517 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3518 TestLoadTimingNotReusedWithPac(load_timing_info,
3519 CONNECT_TIMING_HAS_SSL_TIMES);
3520
[email protected]0b0bf032010-09-21 18:08:503521 trans.reset();
[email protected]102e27c2011-02-23 01:01:313522 session->CloseAllConnections();
[email protected]394816e92010-08-03 07:38:593523}
3524
[email protected]11203f012009-11-12 23:02:313525// Test the request-challenge-retry sequence for basic auth, over a keep-alive
ttuttle34f63b52015-03-05 04:33:013526// proxy connection with HTTP/1.0 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013527TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp10) {
mmenked39192ee2015-12-09 00:57:233528 // On the second pass, the body read of the auth challenge is synchronous, so
3529 // IsConnectedAndIdle returns false. The socket should still be drained and
3530 // reused. See http://crbug.com/544255.
3531 for (int i = 0; i < 2; ++i) {
3532 HttpRequestInfo request;
3533 request.method = "GET";
3534 request.url = GURL("https://www.example.org/");
3535 // Ensure that proxy authentication is attempted even
3536 // when the no authentication data flag is set.
3537 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103538 request.traffic_annotation =
3539 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle34f63b52015-03-05 04:33:013540
mmenked39192ee2015-12-09 00:57:233541 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593542 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493543 ProxyResolutionService::CreateFixed("myproxy:70",
3544 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233545 BoundTestNetLog log;
3546 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093547 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle34f63b52015-03-05 04:33:013548
bnc691fda62016-08-12 00:43:163549 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle34f63b52015-03-05 04:33:013550
mmenked39192ee2015-12-09 00:57:233551 // Since we have proxy, should try to establish tunnel.
3552 MockWrite data_writes1[] = {
3553 MockWrite(ASYNC, 0,
3554 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3555 "Host: www.example.org:443\r\n"
3556 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle34f63b52015-03-05 04:33:013557
bnc691fda62016-08-12 00:43:163558 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233559 // be issuing -- the final header line contains the credentials.
3560 MockWrite(ASYNC, 3,
3561 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3562 "Host: www.example.org:443\r\n"
3563 "Proxy-Connection: keep-alive\r\n"
3564 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3565 };
ttuttle34f63b52015-03-05 04:33:013566
mmenked39192ee2015-12-09 00:57:233567 // The proxy responds to the connect with a 407, using a persistent
3568 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3569 MockRead data_reads1[] = {
3570 // No credentials.
3571 MockRead(ASYNC, 1,
3572 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3573 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3574 "Proxy-Connection: keep-alive\r\n"
3575 "Content-Length: 10\r\n\r\n"),
3576 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
ttuttle34f63b52015-03-05 04:33:013577
mmenked39192ee2015-12-09 00:57:233578 // Wrong credentials (wrong password).
3579 MockRead(ASYNC, 4,
3580 "HTTP/1.0 407 Proxy Authentication Required\r\n"
3581 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3582 "Proxy-Connection: keep-alive\r\n"
3583 "Content-Length: 10\r\n\r\n"),
3584 // No response body because the test stops reading here.
3585 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3586 };
ttuttle34f63b52015-03-05 04:33:013587
Ryan Sleevib8d7ea02018-05-07 20:01:013588 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233589 data1.set_busy_before_sync_reads(true);
3590 session_deps_.socket_factory->AddSocketDataProvider(&data1);
ttuttle34f63b52015-03-05 04:33:013591
mmenked39192ee2015-12-09 00:57:233592 TestCompletionCallback callback1;
ttuttle34f63b52015-03-05 04:33:013593
bnc691fda62016-08-12 00:43:163594 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013595 EXPECT_THAT(callback1.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013596
mmenked39192ee2015-12-09 00:57:233597 TestNetLogEntry::List entries;
3598 log.GetEntries(&entries);
3599 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003600 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3601 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233602 ExpectLogContainsSomewhere(
3603 entries, pos,
mikecirone8b85c432016-09-08 19:11:003604 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3605 NetLogEventPhase::NONE);
ttuttle34f63b52015-03-05 04:33:013606
bnc691fda62016-08-12 00:43:163607 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233608 ASSERT_TRUE(response);
3609 ASSERT_TRUE(response->headers);
3610 EXPECT_TRUE(response->headers->IsKeepAlive());
3611 EXPECT_EQ(407, response->headers->response_code());
3612 EXPECT_EQ(10, response->headers->GetContentLength());
3613 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583614 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
ttuttle34f63b52015-03-05 04:33:013615
mmenked39192ee2015-12-09 00:57:233616 TestCompletionCallback callback2;
ttuttle34f63b52015-03-05 04:33:013617
mmenked39192ee2015-12-09 00:57:233618 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163619 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3620 callback2.callback());
robpercival214763f2016-07-01 23:27:013621 EXPECT_THAT(callback2.GetResult(rv), IsOk());
ttuttle34f63b52015-03-05 04:33:013622
bnc691fda62016-08-12 00:43:163623 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233624 ASSERT_TRUE(response);
3625 ASSERT_TRUE(response->headers);
3626 EXPECT_TRUE(response->headers->IsKeepAlive());
3627 EXPECT_EQ(407, response->headers->response_code());
3628 EXPECT_EQ(10, response->headers->GetContentLength());
3629 EXPECT_TRUE(HttpVersion(1, 0) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583630 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
ttuttle34f63b52015-03-05 04:33:013631
mmenked39192ee2015-12-09 00:57:233632 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3633 // out of scope.
3634 session->CloseAllConnections();
3635 }
ttuttle34f63b52015-03-05 04:33:013636}
3637
3638// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3639// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel.
bncd16676a2016-07-20 16:23:013640TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHttp11) {
mmenked39192ee2015-12-09 00:57:233641 // On the second pass, the body read of the auth challenge is synchronous, so
3642 // IsConnectedAndIdle returns false. The socket should still be drained and
3643 // reused. See http://crbug.com/544255.
3644 for (int i = 0; i < 2; ++i) {
3645 HttpRequestInfo request;
3646 request.method = "GET";
3647 request.url = GURL("https://www.example.org/");
3648 // Ensure that proxy authentication is attempted even
3649 // when the no authentication data flag is set.
3650 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103651 request.traffic_annotation =
3652 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233653
3654 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593655 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493656 ProxyResolutionService::CreateFixed("myproxy:70",
3657 TRAFFIC_ANNOTATION_FOR_TESTS);
mmenked39192ee2015-12-09 00:57:233658 BoundTestNetLog log;
3659 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093660 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
mmenked39192ee2015-12-09 00:57:233661
bnc691fda62016-08-12 00:43:163662 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenked39192ee2015-12-09 00:57:233663
3664 // Since we have proxy, should try to establish tunnel.
3665 MockWrite data_writes1[] = {
3666 MockWrite(ASYNC, 0,
3667 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3668 "Host: www.example.org:443\r\n"
3669 "Proxy-Connection: keep-alive\r\n\r\n"),
3670
bnc691fda62016-08-12 00:43:163671 // After calling trans.RestartWithAuth(), this is the request we should
mmenked39192ee2015-12-09 00:57:233672 // be issuing -- the final header line contains the credentials.
3673 MockWrite(ASYNC, 3,
3674 "CONNECT www.example.org:443 HTTP/1.1\r\n"
3675 "Host: www.example.org:443\r\n"
3676 "Proxy-Connection: keep-alive\r\n"
3677 "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
3678 };
3679
3680 // The proxy responds to the connect with a 407, using a persistent
3681 // connection. (Since it's HTTP/1.0, keep-alive has to be explicit.)
3682 MockRead data_reads1[] = {
3683 // No credentials.
3684 MockRead(ASYNC, 1,
3685 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3686 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3687 "Content-Length: 10\r\n\r\n"),
3688 MockRead(i == 0 ? ASYNC : SYNCHRONOUS, 2, "0123456789"),
3689
3690 // Wrong credentials (wrong password).
3691 MockRead(ASYNC, 4,
3692 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3693 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3694 "Content-Length: 10\r\n\r\n"),
3695 // No response body because the test stops reading here.
3696 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 5),
3697 };
3698
Ryan Sleevib8d7ea02018-05-07 20:01:013699 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233700 data1.set_busy_before_sync_reads(true);
3701 session_deps_.socket_factory->AddSocketDataProvider(&data1);
3702
3703 TestCompletionCallback callback1;
3704
bnc691fda62016-08-12 00:43:163705 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013706 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233707
3708 TestNetLogEntry::List entries;
3709 log.GetEntries(&entries);
3710 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003711 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3712 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233713 ExpectLogContainsSomewhere(
3714 entries, pos,
mikecirone8b85c432016-09-08 19:11:003715 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3716 NetLogEventPhase::NONE);
mmenked39192ee2015-12-09 00:57:233717
bnc691fda62016-08-12 00:43:163718 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233719 ASSERT_TRUE(response);
3720 ASSERT_TRUE(response->headers);
3721 EXPECT_TRUE(response->headers->IsKeepAlive());
3722 EXPECT_EQ(407, response->headers->response_code());
3723 EXPECT_EQ(10, response->headers->GetContentLength());
3724 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583725 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
Wojciech Dzierżanowski0950c372019-04-02 19:29:503726 EXPECT_FALSE(response->did_use_http_auth);
mmenked39192ee2015-12-09 00:57:233727
3728 TestCompletionCallback callback2;
3729
3730 // Wrong password (should be "bar").
bnc691fda62016-08-12 00:43:163731 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz),
3732 callback2.callback());
robpercival214763f2016-07-01 23:27:013733 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233734
bnc691fda62016-08-12 00:43:163735 response = trans.GetResponseInfo();
mmenked39192ee2015-12-09 00:57:233736 ASSERT_TRUE(response);
3737 ASSERT_TRUE(response->headers);
3738 EXPECT_TRUE(response->headers->IsKeepAlive());
3739 EXPECT_EQ(407, response->headers->response_code());
3740 EXPECT_EQ(10, response->headers->GetContentLength());
3741 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583742 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
Wojciech Dzierżanowski0950c372019-04-02 19:29:503743 EXPECT_TRUE(response->did_use_http_auth);
mmenked39192ee2015-12-09 00:57:233744
3745 // Flush the idle socket before the NetLog and HttpNetworkTransaction go
3746 // out of scope.
3747 session->CloseAllConnections();
3748 }
3749}
3750
3751// Test the request-challenge-retry sequence for basic auth, over a keep-alive
3752// proxy connection with HTTP/1.1 responses, when setting up an SSL tunnel, in
3753// the case the server sends extra data on the original socket, so it can't be
3754// reused.
bncd16676a2016-07-20 16:23:013755TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveExtraData) {
[email protected]cb9bf6ca2011-01-28 13:15:273756 HttpRequestInfo request;
3757 request.method = "GET";
bncce36dca22015-04-21 22:11:233758 request.url = GURL("https://www.example.org/");
[email protected]cb9bf6ca2011-01-28 13:15:273759 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:293760 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103761 request.traffic_annotation =
3762 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273763
[email protected]2d2697f92009-02-18 21:00:323764 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:593765 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:493766 ProxyResolutionService::CreateFixedFromPacResult(
3767 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:513768 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:073769 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:093770 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2d2697f92009-02-18 21:00:323771
[email protected]2d2697f92009-02-18 21:00:323772 // Since we have proxy, should try to establish tunnel.
3773 MockWrite data_writes1[] = {
mmenked39192ee2015-12-09 00:57:233774 MockWrite(ASYNC, 0,
3775 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173776 "Host: www.example.org:443\r\n"
3777 "Proxy-Connection: keep-alive\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233778 };
[email protected]2d2697f92009-02-18 21:00:323779
mmenked39192ee2015-12-09 00:57:233780 // The proxy responds to the connect with a 407, using a persistent, but sends
3781 // extra data, so the socket cannot be reused.
3782 MockRead data_reads1[] = {
3783 // No credentials.
3784 MockRead(ASYNC, 1,
3785 "HTTP/1.1 407 Proxy Authentication Required\r\n"
3786 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
3787 "Content-Length: 10\r\n\r\n"),
3788 MockRead(SYNCHRONOUS, 2, "0123456789"),
3789 MockRead(SYNCHRONOUS, 3, "I'm broken!"),
3790 };
3791
3792 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:233793 // After calling trans->RestartWithAuth(), this is the request we should
3794 // be issuing -- the final header line contains the credentials.
mmenked39192ee2015-12-09 00:57:233795 MockWrite(ASYNC, 0,
3796 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173797 "Host: www.example.org:443\r\n"
3798 "Proxy-Connection: keep-alive\r\n"
mmenked39192ee2015-12-09 00:57:233799 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3800
3801 MockWrite(ASYNC, 2,
3802 "GET / HTTP/1.1\r\n"
3803 "Host: www.example.org\r\n"
3804 "Connection: keep-alive\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323805 };
3806
mmenked39192ee2015-12-09 00:57:233807 MockRead data_reads2[] = {
3808 MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]2d2697f92009-02-18 21:00:323809
mmenked39192ee2015-12-09 00:57:233810 MockRead(ASYNC, 3,
3811 "HTTP/1.1 200 OK\r\n"
3812 "Content-Type: text/html; charset=iso-8859-1\r\n"
3813 "Content-Length: 5\r\n\r\n"),
3814 // No response body because the test stops reading here.
3815 MockRead(SYNCHRONOUS, ERR_UNEXPECTED, 4),
[email protected]2d2697f92009-02-18 21:00:323816 };
3817
Ryan Sleevib8d7ea02018-05-07 20:01:013818 SequencedSocketData data1(data_reads1, data_writes1);
mmenked39192ee2015-12-09 00:57:233819 data1.set_busy_before_sync_reads(true);
[email protected]bb88e1d32013-05-03 23:11:073820 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013821 SequencedSocketData data2(data_reads2, data_writes2);
mmenked39192ee2015-12-09 00:57:233822 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3823 SSLSocketDataProvider ssl(ASYNC, OK);
3824 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d2697f92009-02-18 21:00:323825
[email protected]49639fa2011-12-20 23:22:413826 TestCompletionCallback callback1;
[email protected]2d2697f92009-02-18 21:00:323827
bnc87dcefc2017-05-25 12:47:583828 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:193829 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d2697f92009-02-18 21:00:323830
mmenked39192ee2015-12-09 00:57:233831 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:013832 EXPECT_THAT(callback1.GetResult(rv), IsOk());
mmenked39192ee2015-12-09 00:57:233833
mmenke43758e62015-05-04 21:09:463834 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:403835 log.GetEntries(&entries);
[email protected]dbb83db2010-05-11 18:13:393836 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:003837 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
3838 NetLogEventPhase::NONE);
[email protected]dbb83db2010-05-11 18:13:393839 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:403840 entries, pos,
mikecirone8b85c432016-09-08 19:11:003841 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
3842 NetLogEventPhase::NONE);
[email protected]2d2697f92009-02-18 21:00:323843
[email protected]1c773ea12009-04-28 19:58:423844 const HttpResponseInfo* response = trans->GetResponseInfo();
ttuttle7933c112015-01-06 00:55:243845 ASSERT_TRUE(response);
3846 ASSERT_TRUE(response->headers);
[email protected]2d2697f92009-02-18 21:00:323847 EXPECT_TRUE(response->headers->IsKeepAlive());
3848 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:423849 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:583850 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
[email protected]2d2697f92009-02-18 21:00:323851
mmenked39192ee2015-12-09 00:57:233852 LoadTimingInfo load_timing_info;
3853 // CONNECT requests and responses are handled at the connect job level, so
3854 // the transaction does not yet have a connection.
3855 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
3856
[email protected]49639fa2011-12-20 23:22:413857 TestCompletionCallback callback2;
[email protected]2d2697f92009-02-18 21:00:323858
mmenked39192ee2015-12-09 00:57:233859 rv =
3860 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:013861 EXPECT_THAT(callback2.GetResult(rv), IsOk());
[email protected]2d2697f92009-02-18 21:00:323862
[email protected]2d2697f92009-02-18 21:00:323863 EXPECT_TRUE(response->headers->IsKeepAlive());
mmenked39192ee2015-12-09 00:57:233864 EXPECT_EQ(200, response->headers->response_code());
3865 EXPECT_EQ(5, response->headers->GetContentLength());
[email protected]1c773ea12009-04-28 19:58:423866 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]e772db3f2010-07-12 18:11:133867
mmenked39192ee2015-12-09 00:57:233868 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:583869 EXPECT_FALSE(response->auth_challenge.has_value());
mmenked39192ee2015-12-09 00:57:233870
3871 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
3872 TestLoadTimingNotReusedWithPac(load_timing_info,
3873 CONNECT_TIMING_HAS_SSL_TIMES);
3874
3875 trans.reset();
[email protected]102e27c2011-02-23 01:01:313876 session->CloseAllConnections();
[email protected]2d2697f92009-02-18 21:00:323877}
3878
mmenkee71e15332015-10-07 16:39:543879// Test the case a proxy closes a socket while the challenge body is being
3880// drained.
bncd16676a2016-07-20 16:23:013881TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAliveHangupDuringBody) {
mmenkee71e15332015-10-07 16:39:543882 HttpRequestInfo request;
3883 request.method = "GET";
3884 request.url = GURL("https://www.example.org/");
3885 // Ensure that proxy authentication is attempted even
3886 // when the no authentication data flag is set.
3887 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:103888 request.traffic_annotation =
3889 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenkee71e15332015-10-07 16:39:543890
3891 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493892 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3893 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:093894 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenkee71e15332015-10-07 16:39:543895
bnc691fda62016-08-12 00:43:163896 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkee71e15332015-10-07 16:39:543897
3898 // Since we have proxy, should try to establish tunnel.
3899 MockWrite data_writes1[] = {
3900 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173901 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543902 "Proxy-Connection: keep-alive\r\n\r\n"),
3903 };
3904
3905 // The proxy responds to the connect with a 407, using a persistent
3906 // connection.
3907 MockRead data_reads1[] = {
3908 // No credentials.
3909 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3910 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3911 MockRead("Content-Length: 10\r\n\r\n"), MockRead("spam!"),
3912 // Server hands up in the middle of the body.
3913 MockRead(ASYNC, ERR_CONNECTION_CLOSED),
3914 };
3915
3916 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:163917 // After calling trans.RestartWithAuth(), this is the request we should
mmenkee71e15332015-10-07 16:39:543918 // be issuing -- the final header line contains the credentials.
3919 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:173920 "Host: www.example.org:443\r\n"
mmenkee71e15332015-10-07 16:39:543921 "Proxy-Connection: keep-alive\r\n"
3922 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
3923
3924 MockWrite("GET / HTTP/1.1\r\n"
3925 "Host: www.example.org\r\n"
3926 "Connection: keep-alive\r\n\r\n"),
3927 };
3928
3929 MockRead data_reads2[] = {
3930 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
3931
3932 MockRead("HTTP/1.1 200 OK\r\n"),
3933 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
3934 MockRead("Content-Length: 5\r\n\r\n"),
3935 MockRead(SYNCHRONOUS, "hello"),
3936 };
3937
Ryan Sleevib8d7ea02018-05-07 20:01:013938 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenkee71e15332015-10-07 16:39:543939 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:013940 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenkee71e15332015-10-07 16:39:543941 session_deps_.socket_factory->AddSocketDataProvider(&data2);
3942 SSLSocketDataProvider ssl(ASYNC, OK);
3943 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
3944
3945 TestCompletionCallback callback;
3946
tfarina42834112016-09-22 13:38:203947 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:013948 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543949
bnc691fda62016-08-12 00:43:163950 const HttpResponseInfo* response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543951 ASSERT_TRUE(response);
3952 ASSERT_TRUE(response->headers);
3953 EXPECT_TRUE(response->headers->IsKeepAlive());
3954 EXPECT_EQ(407, response->headers->response_code());
Emily Starkf2c9bbd2019-04-09 17:08:583955 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
mmenkee71e15332015-10-07 16:39:543956
bnc691fda62016-08-12 00:43:163957 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
robpercival214763f2016-07-01 23:27:013958 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenkee71e15332015-10-07 16:39:543959
bnc691fda62016-08-12 00:43:163960 response = trans.GetResponseInfo();
mmenkee71e15332015-10-07 16:39:543961 ASSERT_TRUE(response);
3962 ASSERT_TRUE(response->headers);
3963 EXPECT_TRUE(response->headers->IsKeepAlive());
3964 EXPECT_EQ(200, response->headers->response_code());
3965 std::string body;
bnc691fda62016-08-12 00:43:163966 EXPECT_THAT(ReadTransaction(&trans, &body), IsOk());
mmenkee71e15332015-10-07 16:39:543967 EXPECT_EQ("hello", body);
3968}
3969
[email protected]a8e9b162009-03-12 00:06:443970// Test that we don't read the response body when we fail to establish a tunnel,
3971// even if the user cancels the proxy's auth attempt.
bncd16676a2016-07-20 16:23:013972TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:273973 HttpRequestInfo request;
3974 request.method = "GET";
bncce36dca22015-04-21 22:11:233975 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:103976 request.traffic_annotation =
3977 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:273978
[email protected]a8e9b162009-03-12 00:06:443979 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:493980 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
3981 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a8e9b162009-03-12 00:06:443982
danakj1fd259a02016-04-16 03:17:093983 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]a8e9b162009-03-12 00:06:443984
bnc691fda62016-08-12 00:43:163985 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]a8e9b162009-03-12 00:06:443986
[email protected]a8e9b162009-03-12 00:06:443987 // Since we have proxy, should try to establish tunnel.
3988 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:173989 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
3990 "Host: www.example.org:443\r\n"
3991 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]a8e9b162009-03-12 00:06:443992 };
3993
3994 // The proxy responds to the connect with a 407.
3995 MockRead data_reads[] = {
ttuttle7933c112015-01-06 00:55:243996 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
3997 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
3998 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:233999 MockRead("0123456789"),
ttuttle7933c112015-01-06 00:55:244000 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]a8e9b162009-03-12 00:06:444001 };
4002
Ryan Sleevib8d7ea02018-05-07 20:01:014003 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:074004 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]a8e9b162009-03-12 00:06:444005
[email protected]49639fa2011-12-20 23:22:414006 TestCompletionCallback callback;
[email protected]a8e9b162009-03-12 00:06:444007
tfarina42834112016-09-22 13:38:204008 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014009 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]a8e9b162009-03-12 00:06:444010
4011 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014012 EXPECT_THAT(rv, IsOk());
[email protected]a8e9b162009-03-12 00:06:444013
bnc691fda62016-08-12 00:43:164014 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:244015 ASSERT_TRUE(response);
4016 ASSERT_TRUE(response->headers);
[email protected]a8e9b162009-03-12 00:06:444017 EXPECT_TRUE(response->headers->IsKeepAlive());
4018 EXPECT_EQ(407, response->headers->response_code());
[email protected]1c773ea12009-04-28 19:58:424019 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]a8e9b162009-03-12 00:06:444020
4021 std::string response_data;
bnc691fda62016-08-12 00:43:164022 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014023 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]e60e47a2010-07-14 03:37:184024
4025 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
[email protected]102e27c2011-02-23 01:01:314026 session->CloseAllConnections();
[email protected]a8e9b162009-03-12 00:06:444027}
4028
ttuttle7933c112015-01-06 00:55:244029// Test that we don't pass extraneous headers from the proxy's response to the
4030// caller when the proxy responds to CONNECT with 407.
bncd16676a2016-07-20 16:23:014031TEST_F(HttpNetworkTransactionTest, SanitizeProxyAuthHeaders) {
ttuttle7933c112015-01-06 00:55:244032 HttpRequestInfo request;
4033 request.method = "GET";
bncce36dca22015-04-21 22:11:234034 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104035 request.traffic_annotation =
4036 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244037
4038 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:494039 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4040 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
ttuttle7933c112015-01-06 00:55:244041
danakj1fd259a02016-04-16 03:17:094042 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
ttuttle7933c112015-01-06 00:55:244043
bnc691fda62016-08-12 00:43:164044 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ttuttle7933c112015-01-06 00:55:244045
4046 // Since we have proxy, should try to establish tunnel.
4047 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:174048 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4049 "Host: www.example.org:443\r\n"
4050 "Proxy-Connection: keep-alive\r\n\r\n"),
ttuttle7933c112015-01-06 00:55:244051 };
4052
4053 // The proxy responds to the connect with a 407.
4054 MockRead data_reads[] = {
4055 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4056 MockRead("X-Foo: bar\r\n"),
4057 MockRead("Set-Cookie: foo=bar\r\n"),
4058 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4059 MockRead("Content-Length: 10\r\n\r\n"),
mmenked39192ee2015-12-09 00:57:234060 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
ttuttle7933c112015-01-06 00:55:244061 };
4062
Ryan Sleevib8d7ea02018-05-07 20:01:014063 StaticSocketDataProvider data(data_reads, data_writes);
ttuttle7933c112015-01-06 00:55:244064 session_deps_.socket_factory->AddSocketDataProvider(&data);
4065
4066 TestCompletionCallback callback;
4067
tfarina42834112016-09-22 13:38:204068 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014069 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
ttuttle7933c112015-01-06 00:55:244070
4071 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014072 EXPECT_THAT(rv, IsOk());
ttuttle7933c112015-01-06 00:55:244073
bnc691fda62016-08-12 00:43:164074 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttle7933c112015-01-06 00:55:244075 ASSERT_TRUE(response);
4076 ASSERT_TRUE(response->headers);
4077 EXPECT_TRUE(response->headers->IsKeepAlive());
4078 EXPECT_EQ(407, response->headers->response_code());
4079 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4080 EXPECT_FALSE(response->headers->HasHeader("X-Foo"));
4081 EXPECT_FALSE(response->headers->HasHeader("Set-Cookie"));
4082
4083 std::string response_data;
bnc691fda62016-08-12 00:43:164084 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:014085 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
ttuttle7933c112015-01-06 00:55:244086
4087 // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
4088 session->CloseAllConnections();
4089}
4090
[email protected]8fdbcd22010-05-05 02:54:524091// Test when a server (non-proxy) returns a 407 (proxy-authenticate).
4092// The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
bncd16676a2016-07-20 16:23:014093TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
[email protected]8fdbcd22010-05-05 02:54:524094 HttpRequestInfo request;
4095 request.method = "GET";
bncce36dca22015-04-21 22:11:234096 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104097 request.traffic_annotation =
4098 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8fdbcd22010-05-05 02:54:524099
[email protected]cb9bf6ca2011-01-28 13:15:274100 // We are using a DIRECT connection (i.e. no proxy) for this session.
danakj1fd259a02016-04-16 03:17:094101 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:164102 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:274103
[email protected]8fdbcd22010-05-05 02:54:524104 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:234105 MockWrite(
4106 "GET / HTTP/1.1\r\n"
4107 "Host: www.example.org\r\n"
4108 "Connection: keep-alive\r\n\r\n"),
[email protected]8fdbcd22010-05-05 02:54:524109 };
4110
4111 MockRead data_reads1[] = {
4112 MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
4113 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4114 // Large content-length -- won't matter, as connection will be reset.
4115 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:064116 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]8fdbcd22010-05-05 02:54:524117 };
4118
Ryan Sleevib8d7ea02018-05-07 20:01:014119 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074120 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8fdbcd22010-05-05 02:54:524121
[email protected]49639fa2011-12-20 23:22:414122 TestCompletionCallback callback;
[email protected]8fdbcd22010-05-05 02:54:524123
tfarina42834112016-09-22 13:38:204124 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014125 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8fdbcd22010-05-05 02:54:524126
4127 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:014128 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
[email protected]8fdbcd22010-05-05 02:54:524129}
4130
[email protected]7a67a8152010-11-05 18:31:104131// Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
4132// through a non-authenticating proxy. The request should fail with
4133// ERR_UNEXPECTED_PROXY_AUTH.
4134// Note that it is impossible to detect if an HTTP server returns a 407 through
4135// a non-authenticating proxy - there is nothing to indicate whether the
4136// response came from the proxy or the server, so it is treated as if the proxy
4137// issued the challenge.
bncd16676a2016-07-20 16:23:014138TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
[email protected]cb9bf6ca2011-01-28 13:15:274139 HttpRequestInfo request;
4140 request.method = "GET";
bncce36dca22015-04-21 22:11:234141 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104142 request.traffic_annotation =
4143 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:274144
Ramin Halavatica8d5252018-03-12 05:33:494145 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
4146 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:514147 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:074148 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:094149 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7a67a8152010-11-05 18:31:104150
[email protected]7a67a8152010-11-05 18:31:104151 // Since we have proxy, should try to establish tunnel.
4152 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:174153 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4154 "Host: www.example.org:443\r\n"
4155 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104156
rsleevidb16bb02015-11-12 23:47:174157 MockWrite("GET / HTTP/1.1\r\n"
4158 "Host: www.example.org\r\n"
4159 "Connection: keep-alive\r\n\r\n"),
[email protected]7a67a8152010-11-05 18:31:104160 };
4161
4162 MockRead data_reads1[] = {
4163 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
4164
4165 MockRead("HTTP/1.1 407 Unauthorized\r\n"),
4166 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
4167 MockRead("\r\n"),
[email protected]8ddf8322012-02-23 18:08:064168 MockRead(SYNCHRONOUS, OK),
[email protected]7a67a8152010-11-05 18:31:104169 };
4170
Ryan Sleevib8d7ea02018-05-07 20:01:014171 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:074172 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:064173 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:074174 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7a67a8152010-11-05 18:31:104175
[email protected]49639fa2011-12-20 23:22:414176 TestCompletionCallback callback1;
[email protected]7a67a8152010-11-05 18:31:104177
bnc691fda62016-08-12 00:43:164178 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]7a67a8152010-11-05 18:31:104179
bnc691fda62016-08-12 00:43:164180 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:014181 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7a67a8152010-11-05 18:31:104182
4183 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:014184 EXPECT_THAT(rv, IsError(ERR_UNEXPECTED_PROXY_AUTH));
mmenke43758e62015-05-04 21:09:464185 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:404186 log.GetEntries(&entries);
[email protected]7a67a8152010-11-05 18:31:104187 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:004188 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
4189 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104190 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:404191 entries, pos,
mikecirone8b85c432016-09-08 19:11:004192 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
4193 NetLogEventPhase::NONE);
[email protected]7a67a8152010-11-05 18:31:104194}
[email protected]2df19bb2010-08-25 20:13:464195
mmenke2a1781d2015-10-07 19:25:334196// Test a proxy auth scheme that allows default credentials and a proxy server
4197// that uses non-persistent connections.
bncd16676a2016-07-20 16:23:014198TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334199 AuthAllowsDefaultCredentialsTunnelConnectionClose) {
4200 HttpRequestInfo request;
4201 request.method = "GET";
4202 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104203 request.traffic_annotation =
4204 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334205
4206 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594207 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494208 ProxyResolutionService::CreateFixedFromPacResult(
4209 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334210
Jeremy Roman0579ed62017-08-29 15:56:194211 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334212 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194213 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334214 mock_handler->set_allows_default_credentials(true);
4215 auth_handler_factory->AddMockHandler(mock_handler.release(),
4216 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484217 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334218
4219 // Add NetLog just so can verify load timing information gets a NetLog ID.
4220 NetLog net_log;
4221 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094222 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334223
4224 // Since we have proxy, should try to establish tunnel.
4225 MockWrite data_writes1[] = {
4226 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174227 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334228 "Proxy-Connection: keep-alive\r\n\r\n"),
4229 };
4230
4231 // The proxy responds to the connect with a 407, using a non-persistent
4232 // connection.
4233 MockRead data_reads1[] = {
4234 // No credentials.
4235 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4236 MockRead("Proxy-Authenticate: Mock\r\n"),
4237 MockRead("Proxy-Connection: close\r\n\r\n"),
4238 };
4239
4240 // Since the first connection couldn't be reused, need to establish another
4241 // once given credentials.
4242 MockWrite data_writes2[] = {
4243 // After calling trans->RestartWithAuth(), this is the request we should
4244 // be issuing -- the final header line contains the credentials.
4245 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174246 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334247 "Proxy-Connection: keep-alive\r\n"
4248 "Proxy-Authorization: auth_token\r\n\r\n"),
4249
4250 MockWrite("GET / HTTP/1.1\r\n"
4251 "Host: www.example.org\r\n"
4252 "Connection: keep-alive\r\n\r\n"),
4253 };
4254
4255 MockRead data_reads2[] = {
4256 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4257
4258 MockRead("HTTP/1.1 200 OK\r\n"),
4259 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4260 MockRead("Content-Length: 5\r\n\r\n"),
4261 MockRead(SYNCHRONOUS, "hello"),
4262 };
4263
Ryan Sleevib8d7ea02018-05-07 20:01:014264 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334265 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014266 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334267 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4268 SSLSocketDataProvider ssl(ASYNC, OK);
4269 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4270
bnc87dcefc2017-05-25 12:47:584271 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194272 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334273
4274 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204275 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014276 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334277
4278 const HttpResponseInfo* response = trans->GetResponseInfo();
4279 ASSERT_TRUE(response);
4280 ASSERT_TRUE(response->headers);
4281 EXPECT_FALSE(response->headers->IsKeepAlive());
4282 EXPECT_EQ(407, response->headers->response_code());
4283 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4284 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584285 EXPECT_FALSE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334286
4287 LoadTimingInfo load_timing_info;
4288 // CONNECT requests and responses are handled at the connect job level, so
4289 // the transaction does not yet have a connection.
4290 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4291
4292 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014293 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334294 response = trans->GetResponseInfo();
4295 ASSERT_TRUE(response);
4296 ASSERT_TRUE(response->headers);
4297 EXPECT_TRUE(response->headers->IsKeepAlive());
4298 EXPECT_EQ(200, response->headers->response_code());
4299 EXPECT_EQ(5, response->headers->GetContentLength());
4300 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4301
4302 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:584303 EXPECT_FALSE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334304
4305 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4306 TestLoadTimingNotReusedWithPac(load_timing_info,
4307 CONNECT_TIMING_HAS_SSL_TIMES);
4308
4309 trans.reset();
4310 session->CloseAllConnections();
4311}
4312
4313// Test a proxy auth scheme that allows default credentials and a proxy server
4314// that hangs up when credentials are initially sent.
bncd16676a2016-07-20 16:23:014315TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334316 AuthAllowsDefaultCredentialsTunnelServerClosesConnection) {
4317 HttpRequestInfo request;
4318 request.method = "GET";
4319 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104320 request.traffic_annotation =
4321 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334322
4323 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594324 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494325 ProxyResolutionService::CreateFixedFromPacResult(
4326 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334327
Jeremy Roman0579ed62017-08-29 15:56:194328 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334329 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194330 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334331 mock_handler->set_allows_default_credentials(true);
4332 auth_handler_factory->AddMockHandler(mock_handler.release(),
4333 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484334 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334335
4336 // Add NetLog just so can verify load timing information gets a NetLog ID.
4337 NetLog net_log;
4338 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094339 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334340
4341 // Should try to establish tunnel.
4342 MockWrite data_writes1[] = {
4343 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174344 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334345 "Proxy-Connection: keep-alive\r\n\r\n"),
4346
4347 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174348 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334349 "Proxy-Connection: keep-alive\r\n"
4350 "Proxy-Authorization: auth_token\r\n\r\n"),
4351 };
4352
4353 // The proxy responds to the connect with a 407, using a non-persistent
4354 // connection.
4355 MockRead data_reads1[] = {
4356 // No credentials.
4357 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4358 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4359 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4360 };
4361
4362 // Since the first connection was closed, need to establish another once given
4363 // credentials.
4364 MockWrite data_writes2[] = {
4365 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174366 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334367 "Proxy-Connection: keep-alive\r\n"
4368 "Proxy-Authorization: auth_token\r\n\r\n"),
4369
4370 MockWrite("GET / HTTP/1.1\r\n"
4371 "Host: www.example.org\r\n"
4372 "Connection: keep-alive\r\n\r\n"),
4373 };
4374
4375 MockRead data_reads2[] = {
4376 MockRead("HTTP/1.0 200 Connection Established\r\n\r\n"),
4377
4378 MockRead("HTTP/1.1 200 OK\r\n"),
4379 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
4380 MockRead("Content-Length: 5\r\n\r\n"),
4381 MockRead(SYNCHRONOUS, "hello"),
4382 };
4383
Ryan Sleevib8d7ea02018-05-07 20:01:014384 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334385 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014386 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334387 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4388 SSLSocketDataProvider ssl(ASYNC, OK);
4389 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4390
bnc87dcefc2017-05-25 12:47:584391 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194392 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334393
4394 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204395 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014396 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334397
4398 const HttpResponseInfo* response = trans->GetResponseInfo();
4399 ASSERT_TRUE(response);
4400 ASSERT_TRUE(response->headers);
4401 EXPECT_TRUE(response->headers->IsKeepAlive());
4402 EXPECT_EQ(407, response->headers->response_code());
4403 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4404 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584405 EXPECT_FALSE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334406
4407 LoadTimingInfo load_timing_info;
4408 // CONNECT requests and responses are handled at the connect job level, so
4409 // the transaction does not yet have a connection.
4410 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4411
4412 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014413 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334414
4415 response = trans->GetResponseInfo();
4416 ASSERT_TRUE(response);
4417 ASSERT_TRUE(response->headers);
4418 EXPECT_TRUE(response->headers->IsKeepAlive());
4419 EXPECT_EQ(200, response->headers->response_code());
4420 EXPECT_EQ(5, response->headers->GetContentLength());
4421 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4422
4423 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:584424 EXPECT_FALSE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334425
4426 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
4427 TestLoadTimingNotReusedWithPac(load_timing_info,
4428 CONNECT_TIMING_HAS_SSL_TIMES);
4429
4430 trans.reset();
4431 session->CloseAllConnections();
4432}
4433
4434// Test a proxy auth scheme that allows default credentials and a proxy server
4435// that hangs up when credentials are initially sent, and hangs up again when
4436// they are retried.
bncd16676a2016-07-20 16:23:014437TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334438 AuthAllowsDefaultCredentialsTunnelServerClosesConnectionTwice) {
4439 HttpRequestInfo request;
4440 request.method = "GET";
4441 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104442 request.traffic_annotation =
4443 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334444
4445 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594446 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494447 ProxyResolutionService::CreateFixedFromPacResult(
4448 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334449
Jeremy Roman0579ed62017-08-29 15:56:194450 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334451 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194452 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334453 mock_handler->set_allows_default_credentials(true);
4454 auth_handler_factory->AddMockHandler(mock_handler.release(),
4455 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484456 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334457
4458 // Add NetLog just so can verify load timing information gets a NetLog ID.
4459 NetLog net_log;
4460 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094461 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334462
4463 // Should try to establish tunnel.
4464 MockWrite data_writes1[] = {
4465 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174466 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334467 "Proxy-Connection: keep-alive\r\n\r\n"),
4468
4469 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174470 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334471 "Proxy-Connection: keep-alive\r\n"
4472 "Proxy-Authorization: auth_token\r\n\r\n"),
4473 };
4474
4475 // The proxy responds to the connect with a 407, and then hangs up after the
4476 // second request is sent.
4477 MockRead data_reads1[] = {
4478 // No credentials.
4479 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4480 MockRead("Content-Length: 0\r\n"),
4481 MockRead("Proxy-Connection: keep-alive\r\n"),
4482 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4483 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4484 };
4485
4486 // HttpNetworkTransaction sees a reused connection that was closed with
4487 // ERR_CONNECTION_CLOSED, realized it might have been a race, so retries the
4488 // request.
4489 MockWrite data_writes2[] = {
4490 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174491 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334492 "Proxy-Connection: keep-alive\r\n\r\n"),
4493 };
4494
4495 // The proxy, having had more than enough of us, just hangs up.
4496 MockRead data_reads2[] = {
4497 // No credentials.
4498 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4499 };
4500
Ryan Sleevib8d7ea02018-05-07 20:01:014501 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334502 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014503 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334504 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4505
bnc87dcefc2017-05-25 12:47:584506 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194507 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334508
4509 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204510 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014511 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334512
4513 const HttpResponseInfo* response = trans->GetResponseInfo();
4514 ASSERT_TRUE(response);
4515 ASSERT_TRUE(response->headers);
4516 EXPECT_TRUE(response->headers->IsKeepAlive());
4517 EXPECT_EQ(407, response->headers->response_code());
4518 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4519 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584520 EXPECT_FALSE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334521
4522 LoadTimingInfo load_timing_info;
4523 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4524
4525 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014526 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_EMPTY_RESPONSE));
mmenke2a1781d2015-10-07 19:25:334527
4528 trans.reset();
4529 session->CloseAllConnections();
4530}
4531
Asanka Herathbc3f8f62018-11-16 23:08:304532// This test exercises an odd edge case where the proxy closes the connection
4533// after the authentication handshake is complete. Presumably this technique is
4534// used in lieu of returning a 403 or 5xx status code when the authentication
4535// succeeds, but the user is not authorized to connect to the destination
4536// server. There's no standard for what a proxy should do to indicate a blocked
4537// site.
4538TEST_F(HttpNetworkTransactionTest,
4539 AuthAllowsDefaultCredentialsTunnelConnectionClosesBeforeBody) {
4540 HttpRequestInfo request;
4541 request.method = "GET";
4542 request.url = GURL("https://www.example.org/");
4543 request.traffic_annotation =
4544 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4545
4546 // Configure against proxy server "myproxy:70".
4547 session_deps_.proxy_resolution_service =
4548 ProxyResolutionService::CreateFixedFromPacResult(
4549 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
4550
Asanka Herathbc3f8f62018-11-16 23:08:304551 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
4552 auth_handler_factory->set_do_init_from_challenge(true);
4553
4554 // Create two mock AuthHandlers. This is because the transaction gets retried
4555 // after the first ERR_CONNECTION_CLOSED since it's ambiguous whether there
4556 // was a real network error.
4557 //
4558 // The handlers support both default and explicit credentials. The retry
4559 // mentioned above should be able to reuse the default identity. Thus there
4560 // should never be a need to prompt for explicit credentials.
4561 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
4562 mock_handler->set_allows_default_credentials(true);
4563 mock_handler->set_allows_explicit_credentials(true);
4564 mock_handler->set_connection_based(true);
4565 auth_handler_factory->AddMockHandler(mock_handler.release(),
4566 HttpAuth::AUTH_PROXY);
4567 mock_handler = std::make_unique<HttpAuthHandlerMock>();
4568 mock_handler->set_allows_default_credentials(true);
4569 mock_handler->set_allows_explicit_credentials(true);
4570 mock_handler->set_connection_based(true);
4571 auth_handler_factory->AddMockHandler(mock_handler.release(),
4572 HttpAuth::AUTH_PROXY);
4573 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4574
4575 NetLog net_log;
4576 session_deps_.net_log = &net_log;
4577 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4578
4579 // Data for both sockets.
4580 //
4581 // Writes are for the tunnel establishment attempts and the
4582 // authentication handshake.
4583 MockWrite data_writes1[] = {
4584 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4585 "Host: www.example.org:443\r\n"
4586 "Proxy-Connection: keep-alive\r\n\r\n"),
4587
4588 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4589 "Host: www.example.org:443\r\n"
4590 "Proxy-Connection: keep-alive\r\n"
4591 "Proxy-Authorization: auth_token\r\n\r\n"),
4592
4593 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
4594 "Host: www.example.org:443\r\n"
4595 "Proxy-Connection: keep-alive\r\n"
4596 "Proxy-Authorization: auth_token\r\n\r\n"),
4597 };
4598
4599 // The server side of the authentication handshake. Note that the response to
4600 // the final CONNECT request is ERR_CONNECTION_CLOSED.
4601 MockRead data_reads1[] = {
4602 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4603 MockRead("Content-Length: 0\r\n"),
4604 MockRead("Proxy-Connection: keep-alive\r\n"),
4605 MockRead("Proxy-Authenticate: Mock\r\n\r\n"),
4606
4607 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4608 MockRead("Content-Length: 0\r\n"),
4609 MockRead("Proxy-Connection: keep-alive\r\n"),
4610 MockRead("Proxy-Authenticate: Mock foo\r\n\r\n"),
4611
4612 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED),
4613 };
4614
4615 StaticSocketDataProvider data1(data_reads1, data_writes1);
4616 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4617
4618 // The second socket is for the reconnection attempt. Data is identical to the
4619 // first attempt.
4620 StaticSocketDataProvider data2(data_reads1, data_writes1);
4621 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4622
4623 auto trans =
4624 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
4625
4626 TestCompletionCallback callback;
4627 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4628
4629 // Two rounds per handshake. After one retry, the error is propagated up the
4630 // stack.
4631 for (int i = 0; i < 4; ++i) {
4632 EXPECT_THAT(callback.GetResult(rv), IsOk());
4633
4634 const HttpResponseInfo* response = trans->GetResponseInfo();
4635 ASSERT_TRUE(response);
4636 ASSERT_TRUE(response->headers);
4637 EXPECT_EQ(407, response->headers->response_code());
4638 ASSERT_TRUE(trans->IsReadyToRestartForAuth());
4639
4640 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4641 }
4642
4643 // One shall be the number thou shalt retry, and the number of the retrying
4644 // shall be one. Two shalt thou not retry, neither retry thou zero, excepting
4645 // that thou then proceed to one. Three is right out. Once the number one,
4646 // being the first number, be reached, then lobbest thou thy
4647 // ERR_CONNECTION_CLOSED towards they network transaction, who shall snuff it.
4648 EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.GetResult(rv));
4649
4650 trans.reset();
4651 session->CloseAllConnections();
4652}
4653
mmenke2a1781d2015-10-07 19:25:334654// Test a proxy auth scheme that allows default credentials and a proxy server
4655// that hangs up when credentials are initially sent, and sends a challenge
4656// again they are retried.
bncd16676a2016-07-20 16:23:014657TEST_F(HttpNetworkTransactionTest,
mmenke2a1781d2015-10-07 19:25:334658 AuthAllowsDefaultCredentialsTunnelServerChallengesTwice) {
4659 HttpRequestInfo request;
4660 request.method = "GET";
4661 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104662 request.traffic_annotation =
4663 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334664
4665 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:594666 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:494667 ProxyResolutionService::CreateFixedFromPacResult(
4668 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
mmenke2a1781d2015-10-07 19:25:334669
Jeremy Roman0579ed62017-08-29 15:56:194670 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
mmenke2a1781d2015-10-07 19:25:334671 auth_handler_factory->set_do_init_from_challenge(true);
Jeremy Roman0579ed62017-08-29 15:56:194672 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334673 mock_handler->set_allows_default_credentials(true);
4674 auth_handler_factory->AddMockHandler(mock_handler.release(),
4675 HttpAuth::AUTH_PROXY);
4676 // Add another handler for the second challenge. It supports default
4677 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194678 mock_handler = std::make_unique<HttpAuthHandlerMock>();
mmenke2a1781d2015-10-07 19:25:334679 mock_handler->set_allows_default_credentials(true);
4680 auth_handler_factory->AddMockHandler(mock_handler.release(),
4681 HttpAuth::AUTH_PROXY);
dchengc7eeda422015-12-26 03:56:484682 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
mmenke2a1781d2015-10-07 19:25:334683
4684 // Add NetLog just so can verify load timing information gets a NetLog ID.
4685 NetLog net_log;
4686 session_deps_.net_log = &net_log;
danakj1fd259a02016-04-16 03:17:094687 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
mmenke2a1781d2015-10-07 19:25:334688
4689 // Should try to establish tunnel.
4690 MockWrite data_writes1[] = {
4691 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174692 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334693 "Proxy-Connection: keep-alive\r\n\r\n"),
4694 };
4695
4696 // The proxy responds to the connect with a 407, using a non-persistent
4697 // connection.
4698 MockRead data_reads1[] = {
4699 // No credentials.
4700 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4701 MockRead("Proxy-Authenticate: Mock\r\n"),
4702 MockRead("Proxy-Connection: close\r\n\r\n"),
4703 };
4704
4705 // Since the first connection was closed, need to establish another once given
4706 // credentials.
4707 MockWrite data_writes2[] = {
4708 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:174709 "Host: www.example.org:443\r\n"
mmenke2a1781d2015-10-07 19:25:334710 "Proxy-Connection: keep-alive\r\n"
4711 "Proxy-Authorization: auth_token\r\n\r\n"),
4712 };
4713
4714 MockRead data_reads2[] = {
4715 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
4716 MockRead("Proxy-Authenticate: Mock\r\n"),
4717 MockRead("Proxy-Connection: close\r\n\r\n"),
4718 };
4719
Ryan Sleevib8d7ea02018-05-07 20:01:014720 StaticSocketDataProvider data1(data_reads1, data_writes1);
mmenke2a1781d2015-10-07 19:25:334721 session_deps_.socket_factory->AddSocketDataProvider(&data1);
Ryan Sleevib8d7ea02018-05-07 20:01:014722 StaticSocketDataProvider data2(data_reads2, data_writes2);
mmenke2a1781d2015-10-07 19:25:334723 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4724 SSLSocketDataProvider ssl(ASYNC, OK);
4725 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
4726
bnc87dcefc2017-05-25 12:47:584727 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194728 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
mmenke2a1781d2015-10-07 19:25:334729
4730 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:204731 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:014732 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334733
4734 const HttpResponseInfo* response = trans->GetResponseInfo();
4735 ASSERT_TRUE(response);
4736 ASSERT_TRUE(response->headers);
4737 EXPECT_EQ(407, response->headers->response_code());
4738 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4739 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584740 EXPECT_FALSE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334741
4742 LoadTimingInfo load_timing_info;
4743 EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
4744
4745 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
robpercival214763f2016-07-01 23:27:014746 EXPECT_THAT(callback.GetResult(rv), IsOk());
mmenke2a1781d2015-10-07 19:25:334747 response = trans->GetResponseInfo();
4748 ASSERT_TRUE(response);
4749 ASSERT_TRUE(response->headers);
4750 EXPECT_EQ(407, response->headers->response_code());
4751 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584752 EXPECT_TRUE(response->auth_challenge.has_value());
mmenke2a1781d2015-10-07 19:25:334753
4754 trans.reset();
4755 session->CloseAllConnections();
4756}
4757
asankae2257db2016-10-11 22:03:164758// A more nuanced test than GenerateAuthToken test which asserts that
4759// ERR_INVALID_AUTH_CREDENTIALS does not cause the auth scheme to be
4760// unnecessarily invalidated, and that if the server co-operates, the
4761// authentication handshake can continue with the same scheme but with a
4762// different identity.
4763TEST_F(HttpNetworkTransactionTest, NonPermanentGenerateAuthTokenError) {
4764 HttpRequestInfo request;
4765 request.method = "GET";
4766 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:104767 request.traffic_annotation =
4768 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
asankae2257db2016-10-11 22:03:164769
Jeremy Roman0579ed62017-08-29 15:56:194770 auto auth_handler_factory = std::make_unique<HttpAuthHandlerMock::Factory>();
asankae2257db2016-10-11 22:03:164771 auth_handler_factory->set_do_init_from_challenge(true);
4772
4773 // First handler. Uses default credentials, but barfs at generate auth token.
Jeremy Roman0579ed62017-08-29 15:56:194774 auto mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164775 mock_handler->set_allows_default_credentials(true);
4776 mock_handler->set_allows_explicit_credentials(true);
4777 mock_handler->set_connection_based(true);
4778 mock_handler->SetGenerateExpectation(true, ERR_INVALID_AUTH_CREDENTIALS);
4779 auth_handler_factory->AddMockHandler(mock_handler.release(),
4780 HttpAuth::AUTH_SERVER);
4781
4782 // Add another handler for the second challenge. It supports default
4783 // credentials, but they shouldn't be used, since they were already tried.
Jeremy Roman0579ed62017-08-29 15:56:194784 mock_handler = std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:164785 mock_handler->set_allows_default_credentials(true);
4786 mock_handler->set_allows_explicit_credentials(true);
4787 mock_handler->set_connection_based(true);
4788 auth_handler_factory->AddMockHandler(mock_handler.release(),
4789 HttpAuth::AUTH_SERVER);
4790 session_deps_.http_auth_handler_factory = std::move(auth_handler_factory);
4791
4792 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4793
4794 MockWrite data_writes1[] = {
4795 MockWrite("GET / HTTP/1.1\r\n"
4796 "Host: www.example.org\r\n"
4797 "Connection: keep-alive\r\n\r\n"),
4798 };
4799
4800 MockRead data_reads1[] = {
4801 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4802 "WWW-Authenticate: Mock\r\n"
4803 "Connection: keep-alive\r\n\r\n"),
4804 };
4805
4806 // Identical to data_writes1[]. The AuthHandler encounters a
4807 // ERR_INVALID_AUTH_CREDENTIALS during the GenerateAuthToken stage, so the
4808 // transaction procceds without an authorization header.
4809 MockWrite data_writes2[] = {
4810 MockWrite("GET / HTTP/1.1\r\n"
4811 "Host: www.example.org\r\n"
4812 "Connection: keep-alive\r\n\r\n"),
4813 };
4814
4815 MockRead data_reads2[] = {
4816 MockRead("HTTP/1.1 401 Authentication Required\r\n"
4817 "WWW-Authenticate: Mock\r\n"
4818 "Connection: keep-alive\r\n\r\n"),
4819 };
4820
4821 MockWrite data_writes3[] = {
4822 MockWrite("GET / HTTP/1.1\r\n"
4823 "Host: www.example.org\r\n"
4824 "Connection: keep-alive\r\n"
4825 "Authorization: auth_token\r\n\r\n"),
4826 };
4827
4828 MockRead data_reads3[] = {
4829 MockRead("HTTP/1.1 200 OK\r\n"
4830 "Content-Length: 5\r\n"
4831 "Content-Type: text/plain\r\n"
4832 "Connection: keep-alive\r\n\r\n"
4833 "Hello"),
4834 };
4835
Ryan Sleevib8d7ea02018-05-07 20:01:014836 StaticSocketDataProvider data1(data_reads1, data_writes1);
asankae2257db2016-10-11 22:03:164837 session_deps_.socket_factory->AddSocketDataProvider(&data1);
4838
Ryan Sleevib8d7ea02018-05-07 20:01:014839 StaticSocketDataProvider data2(data_reads2, data_writes2);
asankae2257db2016-10-11 22:03:164840 session_deps_.socket_factory->AddSocketDataProvider(&data2);
4841
Ryan Sleevib8d7ea02018-05-07 20:01:014842 StaticSocketDataProvider data3(data_reads3, data_writes3);
asankae2257db2016-10-11 22:03:164843 session_deps_.socket_factory->AddSocketDataProvider(&data3);
4844
bnc87dcefc2017-05-25 12:47:584845 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:194846 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
asankae2257db2016-10-11 22:03:164847
4848 TestCompletionCallback callback;
4849 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
4850 EXPECT_THAT(callback.GetResult(rv), IsOk());
4851
4852 const HttpResponseInfo* response = trans->GetResponseInfo();
4853 ASSERT_TRUE(response);
4854 ASSERT_TRUE(response->headers);
4855 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
4856
4857 // The following three tests assert that an authentication challenge was
4858 // received and that the stack is ready to respond to the challenge using
4859 // ambient credentials.
4860 EXPECT_EQ(401, response->headers->response_code());
4861 EXPECT_TRUE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584862 EXPECT_FALSE(response->auth_challenge.has_value());
asankae2257db2016-10-11 22:03:164863
4864 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4865 EXPECT_THAT(callback.GetResult(rv), IsOk());
4866 response = trans->GetResponseInfo();
4867 ASSERT_TRUE(response);
4868 ASSERT_TRUE(response->headers);
4869
4870 // The following three tests assert that an authentication challenge was
4871 // received and that the stack needs explicit credentials before it is ready
4872 // to respond to the challenge.
4873 EXPECT_EQ(401, response->headers->response_code());
4874 EXPECT_FALSE(trans->IsReadyToRestartForAuth());
Emily Starkf2c9bbd2019-04-09 17:08:584875 EXPECT_TRUE(response->auth_challenge.has_value());
asankae2257db2016-10-11 22:03:164876
4877 rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
4878 EXPECT_THAT(callback.GetResult(rv), IsOk());
4879 response = trans->GetResponseInfo();
4880 ASSERT_TRUE(response);
4881 ASSERT_TRUE(response->headers);
4882 EXPECT_EQ(200, response->headers->response_code());
4883
4884 trans.reset();
4885 session->CloseAllConnections();
4886}
4887
Matt Menked1eb6d42018-01-17 04:54:064888// Proxy resolver that returns a proxy with the same host and port for different
4889// schemes, based on the path of the URL being requests.
4890class SameProxyWithDifferentSchemesProxyResolver : public ProxyResolver {
4891 public:
4892 SameProxyWithDifferentSchemesProxyResolver() {}
4893 ~SameProxyWithDifferentSchemesProxyResolver() override {}
4894
4895 static std::string ProxyHostPortPairAsString() { return "proxy.test:10000"; }
4896
4897 static HostPortPair ProxyHostPortPair() {
4898 return HostPortPair::FromString(ProxyHostPortPairAsString());
4899 }
4900
4901 // ProxyResolver implementation.
4902 int GetProxyForURL(const GURL& url,
4903 ProxyInfo* results,
Bence Békycc5b88a2018-05-25 20:24:174904 CompletionOnceCallback callback,
Matt Menked1eb6d42018-01-17 04:54:064905 std::unique_ptr<Request>* request,
4906 const NetLogWithSource& /*net_log*/) override {
4907 *results = ProxyInfo();
Ramin Halavati921731ea2018-03-16 08:24:574908 results->set_traffic_annotation(
4909 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS));
Matt Menked1eb6d42018-01-17 04:54:064910 if (url.path() == "/socks4") {
4911 results->UsePacString("SOCKS " + ProxyHostPortPairAsString());
4912 return OK;
4913 }
4914 if (url.path() == "/socks5") {
4915 results->UsePacString("SOCKS5 " + ProxyHostPortPairAsString());
4916 return OK;
4917 }
4918 if (url.path() == "/http") {
4919 results->UsePacString("PROXY " + ProxyHostPortPairAsString());
4920 return OK;
4921 }
4922 if (url.path() == "/https") {
4923 results->UsePacString("HTTPS " + ProxyHostPortPairAsString());
4924 return OK;
4925 }
Matt Menkee8648fa2019-01-17 16:47:074926 if (url.path() == "/https_trusted") {
4927 results->UseProxyServer(ProxyServer(ProxyServer::SCHEME_HTTPS,
4928 ProxyHostPortPair(),
4929 true /* is_trusted_proxy */));
4930 return OK;
4931 }
Matt Menked1eb6d42018-01-17 04:54:064932 NOTREACHED();
4933 return ERR_NOT_IMPLEMENTED;
4934 }
4935
4936 private:
4937 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolver);
4938};
4939
4940class SameProxyWithDifferentSchemesProxyResolverFactory
4941 : public ProxyResolverFactory {
4942 public:
4943 SameProxyWithDifferentSchemesProxyResolverFactory()
4944 : ProxyResolverFactory(false) {}
4945
Lily Houghton99597862018-03-07 16:40:424946 int CreateProxyResolver(const scoped_refptr<PacFileData>& pac_script,
4947 std::unique_ptr<ProxyResolver>* resolver,
Bence Békycc5b88a2018-05-25 20:24:174948 CompletionOnceCallback callback,
Lily Houghton99597862018-03-07 16:40:424949 std::unique_ptr<Request>* request) override {
Matt Menked1eb6d42018-01-17 04:54:064950 *resolver = std::make_unique<SameProxyWithDifferentSchemesProxyResolver>();
4951 return OK;
4952 }
4953
4954 private:
4955 DISALLOW_COPY_AND_ASSIGN(SameProxyWithDifferentSchemesProxyResolverFactory);
4956};
4957
4958// Check that when different proxy schemes are all applied to a proxy at the
Matt Menkee8648fa2019-01-17 16:47:074959// same address, the connections are not grouped together. i.e., a request to
Matt Menked1eb6d42018-01-17 04:54:064960// foo.com using proxy.com as an HTTPS proxy won't use the same socket as a
4961// request to foo.com using proxy.com as an HTTP proxy.
4962TEST_F(HttpNetworkTransactionTest, SameDestinationForDifferentProxyTypes) {
Ramin Halavatica8d5252018-03-12 05:33:494963 session_deps_.proxy_resolution_service =
4964 std::make_unique<ProxyResolutionService>(
4965 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
4966 ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)),
4967 std::make_unique<SameProxyWithDifferentSchemesProxyResolverFactory>(),
4968 nullptr);
Matt Menked1eb6d42018-01-17 04:54:064969
4970 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
4971
4972 MockWrite socks_writes[] = {
4973 MockWrite(SYNCHRONOUS, kSOCKS4OkRequestLocalHostPort80,
4974 kSOCKS4OkRequestLocalHostPort80Length),
4975 MockWrite(SYNCHRONOUS,
4976 "GET /socks4 HTTP/1.1\r\n"
4977 "Host: test\r\n"
4978 "Connection: keep-alive\r\n\r\n"),
4979 };
4980 MockRead socks_reads[] = {
4981 MockRead(SYNCHRONOUS, kSOCKS4OkReply, kSOCKS4OkReplyLength),
4982 MockRead("HTTP/1.0 200 OK\r\n"
4983 "Connection: keep-alive\r\n"
4984 "Content-Length: 15\r\n\r\n"
4985 "SOCKS4 Response"),
4986 };
Ryan Sleevib8d7ea02018-05-07 20:01:014987 StaticSocketDataProvider socks_data(socks_reads, socks_writes);
Matt Menked1eb6d42018-01-17 04:54:064988 session_deps_.socket_factory->AddSocketDataProvider(&socks_data);
4989
4990 const char kSOCKS5Request[] = {
4991 0x05, // Version
4992 0x01, // Command (CONNECT)
4993 0x00, // Reserved
4994 0x03, // Address type (DOMAINNAME)
4995 0x04, // Length of domain (4)
4996 't', 'e', 's', 't', // Domain string
4997 0x00, 0x50, // 16-bit port (80)
4998 };
4999 MockWrite socks5_writes[] = {
5000 MockWrite(ASYNC, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
Avi Drissman4365a4782018-12-28 19:26:245001 MockWrite(ASYNC, kSOCKS5Request, base::size(kSOCKS5Request)),
Matt Menked1eb6d42018-01-17 04:54:065002 MockWrite(SYNCHRONOUS,
5003 "GET /socks5 HTTP/1.1\r\n"
5004 "Host: test\r\n"
5005 "Connection: keep-alive\r\n\r\n"),
5006 };
5007 MockRead socks5_reads[] = {
5008 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
5009 MockRead(ASYNC, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
5010 MockRead("HTTP/1.0 200 OK\r\n"
5011 "Connection: keep-alive\r\n"
5012 "Content-Length: 15\r\n\r\n"
5013 "SOCKS5 Response"),
5014 };
Ryan Sleevib8d7ea02018-05-07 20:01:015015 StaticSocketDataProvider socks5_data(socks5_reads, socks5_writes);
Matt Menked1eb6d42018-01-17 04:54:065016 session_deps_.socket_factory->AddSocketDataProvider(&socks5_data);
5017
5018 MockWrite http_writes[] = {
5019 MockWrite(SYNCHRONOUS,
5020 "GET http://test/http HTTP/1.1\r\n"
5021 "Host: test\r\n"
5022 "Proxy-Connection: keep-alive\r\n\r\n"),
5023 };
5024 MockRead http_reads[] = {
5025 MockRead("HTTP/1.1 200 OK\r\n"
5026 "Proxy-Connection: keep-alive\r\n"
5027 "Content-Length: 13\r\n\r\n"
5028 "HTTP Response"),
5029 };
Ryan Sleevib8d7ea02018-05-07 20:01:015030 StaticSocketDataProvider http_data(http_reads, http_writes);
Matt Menked1eb6d42018-01-17 04:54:065031 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
5032
5033 MockWrite https_writes[] = {
5034 MockWrite(SYNCHRONOUS,
5035 "GET http://test/https HTTP/1.1\r\n"
5036 "Host: test\r\n"
5037 "Proxy-Connection: keep-alive\r\n\r\n"),
5038 };
5039 MockRead https_reads[] = {
5040 MockRead("HTTP/1.1 200 OK\r\n"
5041 "Proxy-Connection: keep-alive\r\n"
5042 "Content-Length: 14\r\n\r\n"
5043 "HTTPS Response"),
5044 };
Ryan Sleevib8d7ea02018-05-07 20:01:015045 StaticSocketDataProvider https_data(https_reads, https_writes);
Matt Menked1eb6d42018-01-17 04:54:065046 session_deps_.socket_factory->AddSocketDataProvider(&https_data);
5047 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
5048 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5049
Matt Menkee8648fa2019-01-17 16:47:075050 MockWrite https_trusted_writes[] = {
5051 MockWrite(SYNCHRONOUS,
5052 "GET http://test/https_trusted HTTP/1.1\r\n"
5053 "Host: test\r\n"
5054 "Proxy-Connection: keep-alive\r\n\r\n"),
5055 };
5056 MockRead https_trusted_reads[] = {
5057 MockRead("HTTP/1.1 200 OK\r\n"
5058 "Proxy-Connection: keep-alive\r\n"
5059 "Content-Length: 22\r\n\r\n"
5060 "HTTPS Trusted Response"),
5061 };
5062 StaticSocketDataProvider trusted_https_data(https_trusted_reads,
5063 https_trusted_writes);
5064 session_deps_.socket_factory->AddSocketDataProvider(&trusted_https_data);
5065 SSLSocketDataProvider ssl2(SYNCHRONOUS, OK);
5066 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
5067
Matt Menked1eb6d42018-01-17 04:54:065068 struct TestCase {
5069 GURL url;
5070 std::string expected_response;
Matt Menkee8648fa2019-01-17 16:47:075071 // How many idle sockets there should be in the SOCKS 4/5 proxy socket pools
Matt Menked1eb6d42018-01-17 04:54:065072 // after the test.
Matt Menkee8648fa2019-01-17 16:47:075073 int expected_idle_socks4_sockets;
5074 int expected_idle_socks5_sockets;
5075 // How many idle sockets there should be in the HTTP/HTTPS proxy socket
5076 // pools after the test.
Matt Menked1eb6d42018-01-17 04:54:065077 int expected_idle_http_sockets;
Matt Menkee8648fa2019-01-17 16:47:075078 int expected_idle_https_sockets;
5079 // How many idle sockets there should be in the HTTPS proxy socket pool with
5080 // the ProxyServer's |is_trusted_proxy| bit set after the test.
5081 int expected_idle_trusted_https_sockets;
Matt Menked1eb6d42018-01-17 04:54:065082 } const kTestCases[] = {
Matt Menkee8648fa2019-01-17 16:47:075083 {GURL("http://test/socks4"), "SOCKS4 Response", 1, 0, 0, 0, 0},
5084 {GURL("http://test/socks5"), "SOCKS5 Response", 1, 1, 0, 0, 0},
5085 {GURL("http://test/http"), "HTTP Response", 1, 1, 1, 0, 0},
5086 {GURL("http://test/https"), "HTTPS Response", 1, 1, 1, 1, 0},
5087 {GURL("http://test/https_trusted"), "HTTPS Trusted Response", 1, 1, 1, 1,
5088 1},
Matt Menked1eb6d42018-01-17 04:54:065089 };
5090
5091 for (const auto& test_case : kTestCases) {
5092 HttpRequestInfo request;
5093 request.method = "GET";
5094 request.url = test_case.url;
Ramin Halavatib5e433e62018-02-07 07:41:105095 request.traffic_annotation =
5096 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menked1eb6d42018-01-17 04:54:065097 std::unique_ptr<HttpNetworkTransaction> trans =
5098 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY,
5099 session.get());
5100 TestCompletionCallback callback;
5101 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
5102 EXPECT_THAT(callback.GetResult(rv), IsOk());
5103
5104 const HttpResponseInfo* response = trans->GetResponseInfo();
5105 ASSERT_TRUE(response);
5106 ASSERT_TRUE(response->headers);
5107 EXPECT_EQ(200, response->headers->response_code());
5108 std::string response_data;
5109 EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
5110 EXPECT_EQ(test_case.expected_response, response_data);
5111
5112 // Return the socket to the socket pool, so can make sure it's not used for
5113 // the next requests.
5114 trans.reset();
5115 base::RunLoop().RunUntilIdle();
5116
5117 // Check the number of idle sockets in the pool, to make sure that used
5118 // sockets are indeed being returned to the socket pool. If each request
5119 // doesn't return an idle socket to the pool, the test would incorrectly
5120 // pass.
Matt Menkee8648fa2019-01-17 16:47:075121 EXPECT_EQ(test_case.expected_idle_socks4_sockets,
5122 session
Matt Menked23ab952019-03-06 00:24:405123 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075124 HttpNetworkSession::NORMAL_SOCKET_POOL,
5125 ProxyServer(ProxyServer::SCHEME_SOCKS4,
5126 SameProxyWithDifferentSchemesProxyResolver::
5127 ProxyHostPortPair()))
5128 ->IdleSocketCount());
5129 EXPECT_EQ(test_case.expected_idle_socks5_sockets,
5130 session
Matt Menked23ab952019-03-06 00:24:405131 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075132 HttpNetworkSession::NORMAL_SOCKET_POOL,
5133 ProxyServer(ProxyServer::SCHEME_SOCKS5,
5134 SameProxyWithDifferentSchemesProxyResolver::
5135 ProxyHostPortPair()))
5136 ->IdleSocketCount());
5137 EXPECT_EQ(test_case.expected_idle_http_sockets,
5138 session
Matt Menked23ab952019-03-06 00:24:405139 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075140 HttpNetworkSession::NORMAL_SOCKET_POOL,
5141 ProxyServer(ProxyServer::SCHEME_HTTP,
5142 SameProxyWithDifferentSchemesProxyResolver::
5143 ProxyHostPortPair()))
5144 ->IdleSocketCount());
5145 EXPECT_EQ(test_case.expected_idle_https_sockets,
5146 session
Matt Menked23ab952019-03-06 00:24:405147 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075148 HttpNetworkSession::NORMAL_SOCKET_POOL,
5149 ProxyServer(ProxyServer::SCHEME_HTTPS,
5150 SameProxyWithDifferentSchemesProxyResolver::
5151 ProxyHostPortPair()))
5152 ->IdleSocketCount());
5153 EXPECT_EQ(test_case.expected_idle_trusted_https_sockets,
5154 session
Matt Menked23ab952019-03-06 00:24:405155 ->GetSocketPool(
Matt Menkee8648fa2019-01-17 16:47:075156 HttpNetworkSession::NORMAL_SOCKET_POOL,
5157 ProxyServer(ProxyServer::SCHEME_HTTPS,
5158 SameProxyWithDifferentSchemesProxyResolver::
5159 ProxyHostPortPair(),
5160 true /* is_trusted_proxy */))
5161 ->IdleSocketCount());
Matt Menked1eb6d42018-01-17 04:54:065162 }
5163}
5164
[email protected]029c83b62013-01-24 05:28:205165// Test the load timing for HTTPS requests with an HTTP proxy.
bncd16676a2016-07-20 16:23:015166TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205167 HttpRequestInfo request1;
5168 request1.method = "GET";
bncce36dca22015-04-21 22:11:235169 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e62018-02-07 07:41:105170 request1.traffic_annotation =
5171 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205172
5173 HttpRequestInfo request2;
5174 request2.method = "GET";
bncce36dca22015-04-21 22:11:235175 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e62018-02-07 07:41:105176 request2.traffic_annotation =
5177 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205178
5179 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495180 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5181 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515182 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075183 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095184 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205185
5186 // Since we have proxy, should try to establish tunnel.
5187 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175188 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5189 "Host: www.example.org:443\r\n"
5190 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205191
rsleevidb16bb02015-11-12 23:47:175192 MockWrite("GET /1 HTTP/1.1\r\n"
5193 "Host: www.example.org\r\n"
5194 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205195
rsleevidb16bb02015-11-12 23:47:175196 MockWrite("GET /2 HTTP/1.1\r\n"
5197 "Host: www.example.org\r\n"
5198 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205199 };
5200
5201 // The proxy responds to the connect with a 407, using a persistent
5202 // connection.
5203 MockRead data_reads1[] = {
5204 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5205
5206 MockRead("HTTP/1.1 200 OK\r\n"),
5207 MockRead("Content-Length: 1\r\n\r\n"),
5208 MockRead(SYNCHRONOUS, "1"),
5209
5210 MockRead("HTTP/1.1 200 OK\r\n"),
5211 MockRead("Content-Length: 2\r\n\r\n"),
5212 MockRead(SYNCHRONOUS, "22"),
5213 };
5214
Ryan Sleevib8d7ea02018-05-07 20:01:015215 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075216 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205217 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075218 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205219
5220 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585221 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195222 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205223
5224 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015225 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205226
5227 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015228 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205229
5230 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525231 ASSERT_TRUE(response1);
tbansal2ecbbc72016-10-06 17:15:475232 EXPECT_TRUE(response1->proxy_server.is_http());
wezca1070932016-05-26 20:30:525233 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205234 EXPECT_EQ(1, response1->headers->GetContentLength());
5235
5236 LoadTimingInfo load_timing_info1;
5237 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5238 TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
5239
5240 trans1.reset();
5241
5242 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585243 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195244 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205245
5246 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015247 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205248
5249 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015250 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205251
5252 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525253 ASSERT_TRUE(response2);
tbansal2ecbbc72016-10-06 17:15:475254 EXPECT_TRUE(response2->proxy_server.is_http());
wezca1070932016-05-26 20:30:525255 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205256 EXPECT_EQ(2, response2->headers->GetContentLength());
5257
5258 LoadTimingInfo load_timing_info2;
5259 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5260 TestLoadTimingReused(load_timing_info2);
5261
5262 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5263
5264 trans2.reset();
5265 session->CloseAllConnections();
5266}
5267
5268// Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
bncd16676a2016-07-20 16:23:015269TEST_F(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
[email protected]029c83b62013-01-24 05:28:205270 HttpRequestInfo request1;
5271 request1.method = "GET";
bncce36dca22015-04-21 22:11:235272 request1.url = GURL("https://www.example.org/1");
Ramin Halavatib5e433e62018-02-07 07:41:105273 request1.traffic_annotation =
5274 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205275
5276 HttpRequestInfo request2;
5277 request2.method = "GET";
bncce36dca22015-04-21 22:11:235278 request2.url = GURL("https://www.example.org/2");
Ramin Halavatib5e433e62018-02-07 07:41:105279 request2.traffic_annotation =
5280 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:205281
5282 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:595283 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:495284 ProxyResolutionService::CreateFixedFromPacResult(
5285 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515286 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075287 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095288 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]029c83b62013-01-24 05:28:205289
5290 // Since we have proxy, should try to establish tunnel.
5291 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:175292 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
5293 "Host: www.example.org:443\r\n"
5294 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205295
rsleevidb16bb02015-11-12 23:47:175296 MockWrite("GET /1 HTTP/1.1\r\n"
5297 "Host: www.example.org\r\n"
5298 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205299
rsleevidb16bb02015-11-12 23:47:175300 MockWrite("GET /2 HTTP/1.1\r\n"
5301 "Host: www.example.org\r\n"
5302 "Connection: keep-alive\r\n\r\n"),
[email protected]029c83b62013-01-24 05:28:205303 };
5304
5305 // The proxy responds to the connect with a 407, using a persistent
5306 // connection.
5307 MockRead data_reads1[] = {
5308 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
5309
5310 MockRead("HTTP/1.1 200 OK\r\n"),
5311 MockRead("Content-Length: 1\r\n\r\n"),
5312 MockRead(SYNCHRONOUS, "1"),
5313
5314 MockRead("HTTP/1.1 200 OK\r\n"),
5315 MockRead("Content-Length: 2\r\n\r\n"),
5316 MockRead(SYNCHRONOUS, "22"),
5317 };
5318
Ryan Sleevib8d7ea02018-05-07 20:01:015319 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075320 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]029c83b62013-01-24 05:28:205321 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075322 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]029c83b62013-01-24 05:28:205323
5324 TestCompletionCallback callback1;
bnc87dcefc2017-05-25 12:47:585325 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:195326 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205327
5328 int rv = trans1->Start(&request1, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015329 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205330
5331 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015332 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205333
5334 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:525335 ASSERT_TRUE(response1);
5336 ASSERT_TRUE(response1->headers);
[email protected]029c83b62013-01-24 05:28:205337 EXPECT_EQ(1, response1->headers->GetContentLength());
5338
5339 LoadTimingInfo load_timing_info1;
5340 EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
5341 TestLoadTimingNotReusedWithPac(load_timing_info1,
5342 CONNECT_TIMING_HAS_SSL_TIMES);
5343
5344 trans1.reset();
5345
5346 TestCompletionCallback callback2;
bnc87dcefc2017-05-25 12:47:585347 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:195348 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:205349
5350 rv = trans2->Start(&request2, callback2.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015351 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:205352
5353 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015354 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:205355
5356 const HttpResponseInfo* response2 = trans2->GetResponseInfo();
wezca1070932016-05-26 20:30:525357 ASSERT_TRUE(response2);
5358 ASSERT_TRUE(response2->headers);
[email protected]029c83b62013-01-24 05:28:205359 EXPECT_EQ(2, response2->headers->GetContentLength());
5360
5361 LoadTimingInfo load_timing_info2;
5362 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
5363 TestLoadTimingReusedWithPac(load_timing_info2);
5364
5365 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
5366
5367 trans2.reset();
5368 session->CloseAllConnections();
5369}
5370
[email protected]2df19bb2010-08-25 20:13:465371// Test a simple get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015372TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275373 HttpRequestInfo request;
5374 request.method = "GET";
bncce36dca22015-04-21 22:11:235375 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105376 request.traffic_annotation =
5377 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275378
[email protected]2df19bb2010-08-25 20:13:465379 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495380 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5381 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515382 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075383 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095384 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2df19bb2010-08-25 20:13:465385
[email protected]2df19bb2010-08-25 20:13:465386 // Since we have proxy, should use full url
5387 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:235388 MockWrite(
5389 "GET http://www.example.org/ HTTP/1.1\r\n"
5390 "Host: www.example.org\r\n"
5391 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:465392 };
5393
5394 MockRead data_reads1[] = {
5395 MockRead("HTTP/1.1 200 OK\r\n"),
5396 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
5397 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:065398 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:465399 };
5400
Ryan Sleevib8d7ea02018-05-07 20:01:015401 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:075402 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:065403 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075404 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:465405
[email protected]49639fa2011-12-20 23:22:415406 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:465407
bnc691fda62016-08-12 00:43:165408 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505409
bnc691fda62016-08-12 00:43:165410 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015411 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:465412
5413 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015414 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:465415
[email protected]58e32bb2013-01-21 18:23:255416 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165417 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255418 TestLoadTimingNotReused(load_timing_info,
5419 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5420
bnc691fda62016-08-12 00:43:165421 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525422 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:465423
tbansal2ecbbc72016-10-06 17:15:475424 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:465425 EXPECT_TRUE(response->headers->IsKeepAlive());
5426 EXPECT_EQ(200, response->headers->response_code());
5427 EXPECT_EQ(100, response->headers->GetContentLength());
5428 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
5429
5430 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:585431 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]2df19bb2010-08-25 20:13:465432}
5433
[email protected]7642b5ae2010-09-01 20:55:175434// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015435TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
[email protected]cb9bf6ca2011-01-28 13:15:275436 HttpRequestInfo request;
5437 request.method = "GET";
bncce36dca22015-04-21 22:11:235438 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105439 request.traffic_annotation =
5440 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275441
[email protected]7642b5ae2010-09-01 20:55:175442 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495443 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5444 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515445 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075446 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095447 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7642b5ae2010-09-01 20:55:175448
bncce36dca22015-04-21 22:11:235449 // fetch http://www.example.org/ via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135450 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455451 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415452 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]7642b5ae2010-09-01 20:55:175453
Ryan Hamilton0239aac2018-05-19 00:03:135454 spdy::SpdySerializedFrame resp(
5455 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
5456 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7642b5ae2010-09-01 20:55:175457 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415458 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]7642b5ae2010-09-01 20:55:175459 };
5460
Ryan Sleevib8d7ea02018-05-07 20:01:015461 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075462 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7642b5ae2010-09-01 20:55:175463
[email protected]8ddf8322012-02-23 18:08:065464 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365465 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075466 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]7642b5ae2010-09-01 20:55:175467
[email protected]49639fa2011-12-20 23:22:415468 TestCompletionCallback callback1;
[email protected]7642b5ae2010-09-01 20:55:175469
bnc691fda62016-08-12 00:43:165470 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:505471
bnc691fda62016-08-12 00:43:165472 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015473 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7642b5ae2010-09-01 20:55:175474
5475 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015476 EXPECT_THAT(rv, IsOk());
[email protected]7642b5ae2010-09-01 20:55:175477
[email protected]58e32bb2013-01-21 18:23:255478 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165479 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255480 TestLoadTimingNotReused(load_timing_info,
5481 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
5482
bnc691fda62016-08-12 00:43:165483 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525484 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:475485 EXPECT_TRUE(response->proxy_server.is_https());
wezca1070932016-05-26 20:30:525486 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025487 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]7642b5ae2010-09-01 20:55:175488
5489 std::string response_data;
bnc691fda62016-08-12 00:43:165490 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235491 EXPECT_EQ(kUploadData, response_data);
[email protected]7642b5ae2010-09-01 20:55:175492}
5493
[email protected]1c173852014-06-19 12:51:505494// Verifies that a session which races and wins against the owning transaction
5495// (completing prior to host resolution), doesn't fail the transaction.
5496// Regression test for crbug.com/334413.
bncd16676a2016-07-20 16:23:015497TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
[email protected]1c173852014-06-19 12:51:505498 HttpRequestInfo request;
5499 request.method = "GET";
bncce36dca22015-04-21 22:11:235500 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105501 request.traffic_annotation =
5502 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c173852014-06-19 12:51:505503
5504 // Configure SPDY proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495505 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5506 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515507 BoundTestNetLog log;
[email protected]1c173852014-06-19 12:51:505508 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095509 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]1c173852014-06-19 12:51:505510
bncce36dca22015-04-21 22:11:235511 // Fetch http://www.example.org/ through the SPDY proxy.
Ryan Hamilton0239aac2018-05-19 00:03:135512 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:455513 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:415514 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]1c173852014-06-19 12:51:505515
Raul Tambre94493c652019-03-11 17:18:355516 spdy::SpdySerializedFrame resp(
5517 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135518 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]1c173852014-06-19 12:51:505519 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415520 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]1c173852014-06-19 12:51:505521 };
5522
Ryan Sleevib8d7ea02018-05-07 20:01:015523 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]1c173852014-06-19 12:51:505524 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5525
5526 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365527 ssl.next_proto = kProtoHTTP2;
[email protected]1c173852014-06-19 12:51:505528 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5529
5530 TestCompletionCallback callback1;
5531
bnc691fda62016-08-12 00:43:165532 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]1c173852014-06-19 12:51:505533
5534 // Stall the hostname resolution begun by the transaction.
[email protected]1c173852014-06-19 12:51:505535 session_deps_.host_resolver->set_ondemand_mode(true);
5536
bnc691fda62016-08-12 00:43:165537 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015538 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c173852014-06-19 12:51:505539
5540 // Race a session to the proxy, which completes first.
5541 session_deps_.host_resolver->set_ondemand_mode(false);
Paul Jensena457017a2018-01-19 23:52:045542 SpdySessionKey key(HostPortPair("proxy", 70), ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:115543 PRIVACY_MODE_DISABLED,
5544 SpdySessionKey::IsProxySession::kTrue, SocketTag());
[email protected]1c173852014-06-19 12:51:505545 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:525546 CreateSpdySession(session.get(), key, log.bound());
[email protected]1c173852014-06-19 12:51:505547
5548 // Unstall the resolution begun by the transaction.
5549 session_deps_.host_resolver->set_ondemand_mode(true);
5550 session_deps_.host_resolver->ResolveAllPending();
5551
5552 EXPECT_FALSE(callback1.have_result());
5553 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015554 EXPECT_THAT(rv, IsOk());
[email protected]1c173852014-06-19 12:51:505555
bnc691fda62016-08-12 00:43:165556 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525557 ASSERT_TRUE(response);
5558 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025559 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]1c173852014-06-19 12:51:505560
5561 std::string response_data;
bnc691fda62016-08-12 00:43:165562 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]1c173852014-06-19 12:51:505563 EXPECT_EQ(kUploadData, response_data);
5564}
5565
[email protected]dc7bd1c52010-11-12 00:01:135566// Test a SPDY get through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015567TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
[email protected]cb9bf6ca2011-01-28 13:15:275568 HttpRequestInfo request;
5569 request.method = "GET";
bncce36dca22015-04-21 22:11:235570 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105571 request.traffic_annotation =
5572 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275573
[email protected]79cb5c12011-09-12 13:12:045574 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495575 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5576 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515577 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075578 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095579 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]dc7bd1c52010-11-12 00:01:135580
[email protected]dc7bd1c52010-11-12 00:01:135581 // The first request will be a bare GET, the second request will be a
5582 // GET with a Proxy-Authorization header.
bncb26024382016-06-29 02:39:455583 spdy_util_.set_default_url(request.url);
Ryan Hamilton0239aac2018-05-19 00:03:135584 spdy::SpdySerializedFrame req_get(
Bence Béky27ad0a12018-02-08 00:35:485585 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:385586 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]dc7bd1c52010-11-12 00:01:135587 const char* const kExtraAuthorizationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465588 "proxy-authorization", "Basic Zm9vOmJhcg=="
[email protected]dc7bd1c52010-11-12 00:01:135589 };
Ryan Hamilton0239aac2018-05-19 00:03:135590 spdy::SpdySerializedFrame req_get_authorization(spdy_util_.ConstructSpdyGet(
Avi Drissman4365a4782018-12-28 19:26:245591 kExtraAuthorizationHeaders, base::size(kExtraAuthorizationHeaders) / 2, 3,
Bence Béky27ad0a12018-02-08 00:35:485592 LOWEST));
[email protected]dc7bd1c52010-11-12 00:01:135593 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415594 CreateMockWrite(req_get, 0), CreateMockWrite(req_get_authorization, 3),
[email protected]dc7bd1c52010-11-12 00:01:135595 };
5596
5597 // The first response is a 407 proxy authentication challenge, and the second
5598 // response will be a 200 response since the second request includes a valid
5599 // Authorization header.
5600 const char* const kExtraAuthenticationHeaders[] = {
[email protected]cdf8f7e72013-05-23 10:56:465601 "proxy-authenticate", "Basic realm=\"MyRealm1\""
[email protected]dc7bd1c52010-11-12 00:01:135602 };
Ryan Hamilton0239aac2018-05-19 00:03:135603 spdy::SpdySerializedFrame resp_authentication(
5604 spdy_util_.ConstructSpdyReplyError(
5605 "407", kExtraAuthenticationHeaders,
Avi Drissman4365a4782018-12-28 19:26:245606 base::size(kExtraAuthenticationHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135607 spdy::SpdySerializedFrame body_authentication(
bncdf80d44fd2016-07-15 20:27:415608 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:135609 spdy::SpdySerializedFrame resp_data(
Raul Tambre94493c652019-03-11 17:18:355610 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:135611 spdy::SpdySerializedFrame body_data(
5612 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]dc7bd1c52010-11-12 00:01:135613 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415614 CreateMockRead(resp_authentication, 1),
bnceb9aa7112017-01-05 01:03:465615 CreateMockRead(body_authentication, 2, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:415616 CreateMockRead(resp_data, 4),
5617 CreateMockRead(body_data, 5),
rch8e6c6c42015-05-01 14:05:135618 MockRead(ASYNC, 0, 6),
[email protected]dc7bd1c52010-11-12 00:01:135619 };
5620
Ryan Sleevib8d7ea02018-05-07 20:01:015621 SequencedSocketData data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075622 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]dc7bd1c52010-11-12 00:01:135623
[email protected]8ddf8322012-02-23 18:08:065624 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365625 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075626 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]dc7bd1c52010-11-12 00:01:135627
[email protected]49639fa2011-12-20 23:22:415628 TestCompletionCallback callback1;
[email protected]dc7bd1c52010-11-12 00:01:135629
bnc691fda62016-08-12 00:43:165630 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]dc7bd1c52010-11-12 00:01:135631
bnc691fda62016-08-12 00:43:165632 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015633 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135634
5635 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015636 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135637
bnc691fda62016-08-12 00:43:165638 const HttpResponseInfo* const response = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135639
wezca1070932016-05-26 20:30:525640 ASSERT_TRUE(response);
5641 ASSERT_TRUE(response->headers);
[email protected]dc7bd1c52010-11-12 00:01:135642 EXPECT_EQ(407, response->headers->response_code());
5643 EXPECT_TRUE(response->was_fetched_via_spdy);
Emily Starkf2c9bbd2019-04-09 17:08:585644 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge));
[email protected]dc7bd1c52010-11-12 00:01:135645
[email protected]49639fa2011-12-20 23:22:415646 TestCompletionCallback callback2;
[email protected]dc7bd1c52010-11-12 00:01:135647
bnc691fda62016-08-12 00:43:165648 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:015649 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]dc7bd1c52010-11-12 00:01:135650
5651 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:015652 EXPECT_THAT(rv, IsOk());
[email protected]dc7bd1c52010-11-12 00:01:135653
bnc691fda62016-08-12 00:43:165654 const HttpResponseInfo* const response_restart = trans.GetResponseInfo();
[email protected]dc7bd1c52010-11-12 00:01:135655
wezca1070932016-05-26 20:30:525656 ASSERT_TRUE(response_restart);
5657 ASSERT_TRUE(response_restart->headers);
[email protected]dc7bd1c52010-11-12 00:01:135658 EXPECT_EQ(200, response_restart->headers->response_code());
5659 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:585660 EXPECT_FALSE(response_restart->auth_challenge.has_value());
[email protected]dc7bd1c52010-11-12 00:01:135661}
5662
[email protected]d9da5fe2010-10-13 22:37:165663// Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
bncd16676a2016-07-20 16:23:015664TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
[email protected]cb9bf6ca2011-01-28 13:15:275665 HttpRequestInfo request;
5666 request.method = "GET";
bncce36dca22015-04-21 22:11:235667 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105668 request.traffic_annotation =
5669 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275670
[email protected]d9da5fe2010-10-13 22:37:165671 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495672 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5673 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515674 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075675 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095676 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165677
bnc691fda62016-08-12 00:43:165678 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165679
bncce36dca22015-04-21 22:11:235680 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135681 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:045682 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
5683 HostPortPair("www.example.org", 443)));
bncce36dca22015-04-21 22:11:235684 // fetch https://www.example.org/ via HTTP
[email protected]d9da5fe2010-10-13 22:37:165685
bncce36dca22015-04-21 22:11:235686 const char get[] =
5687 "GET / HTTP/1.1\r\n"
5688 "Host: www.example.org\r\n"
5689 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135690 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:195691 spdy_util_.ConstructSpdyDataFrame(1, get, false));
Ryan Hamilton0239aac2018-05-19 00:03:135692 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:355693 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]d9da5fe2010-10-13 22:37:165694 const char resp[] = "HTTP/1.1 200 OK\r\n"
5695 "Content-Length: 10\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:135696 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:195697 spdy_util_.ConstructSpdyDataFrame(1, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:135698 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:195699 spdy_util_.ConstructSpdyDataFrame(1, "1234567890", false));
Ryan Hamilton0239aac2018-05-19 00:03:135700 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:415701 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
[email protected]8d2f7012012-02-16 00:08:045702
5703 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415704 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5705 CreateMockWrite(window_update, 6),
[email protected]8d2f7012012-02-16 00:08:045706 };
5707
[email protected]d9da5fe2010-10-13 22:37:165708 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415709 CreateMockRead(conn_resp, 1, ASYNC),
5710 CreateMockRead(wrapped_get_resp, 3, ASYNC),
5711 CreateMockRead(wrapped_body, 4, ASYNC),
5712 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135713 MockRead(ASYNC, 0, 7),
[email protected]d9da5fe2010-10-13 22:37:165714 };
5715
Ryan Sleevib8d7ea02018-05-07 20:01:015716 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075717 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165718
[email protected]8ddf8322012-02-23 18:08:065719 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365720 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075721 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065722 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:075723 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165724
[email protected]49639fa2011-12-20 23:22:415725 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165726
bnc691fda62016-08-12 00:43:165727 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015728 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165729
5730 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015731 ASSERT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165732
[email protected]58e32bb2013-01-21 18:23:255733 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165734 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255735 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5736
bnc691fda62016-08-12 00:43:165737 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525738 ASSERT_TRUE(response);
5739 ASSERT_TRUE(response->headers);
[email protected]d9da5fe2010-10-13 22:37:165740 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5741
5742 std::string response_data;
bnc691fda62016-08-12 00:43:165743 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]d9da5fe2010-10-13 22:37:165744 EXPECT_EQ("1234567890", response_data);
5745}
5746
5747// Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
bncd16676a2016-07-20 16:23:015748TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
5749 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:385750
[email protected]cb9bf6ca2011-01-28 13:15:275751 HttpRequestInfo request;
5752 request.method = "GET";
bncce36dca22015-04-21 22:11:235753 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105754 request.traffic_annotation =
5755 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275756
[email protected]d9da5fe2010-10-13 22:37:165757 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495758 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5759 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515760 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075761 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095762 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165763
bnc691fda62016-08-12 00:43:165764 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165765
bncce36dca22015-04-21 22:11:235766 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135767 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:045768 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
5769 HostPortPair("www.example.org", 443)));
bncce36dca22015-04-21 22:11:235770 // fetch https://www.example.org/ via SPDY
5771 const char kMyUrl[] = "https://www.example.org/";
Ryan Hamilton0239aac2018-05-19 00:03:135772 spdy::SpdySerializedFrame get(
bnc38dcd392016-02-09 23:19:495773 spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:135774 spdy::SpdySerializedFrame wrapped_get(
5775 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
5776 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:355777 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135778 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:355779 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135780 spdy::SpdySerializedFrame wrapped_get_resp(
[email protected]23e482282013-06-14 16:08:025781 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135782 spdy::SpdySerializedFrame body(
5783 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
5784 spdy::SpdySerializedFrame wrapped_body(
[email protected]23e482282013-06-14 16:08:025785 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
Ryan Hamilton0239aac2018-05-19 00:03:135786 spdy::SpdySerializedFrame window_update_get_resp(
bncdf80d44fd2016-07-15 20:27:415787 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
Ryan Hamilton0239aac2018-05-19 00:03:135788 spdy::SpdySerializedFrame window_update_body(
bncdf80d44fd2016-07-15 20:27:415789 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
[email protected]8d2f7012012-02-16 00:08:045790
5791 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415792 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_get, 2),
5793 CreateMockWrite(window_update_get_resp, 6),
5794 CreateMockWrite(window_update_body, 7),
[email protected]8d2f7012012-02-16 00:08:045795 };
5796
[email protected]d9da5fe2010-10-13 22:37:165797 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415798 CreateMockRead(conn_resp, 1, ASYNC),
rch32320842015-05-16 15:57:095799 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:415800 CreateMockRead(wrapped_get_resp, 4, ASYNC),
5801 CreateMockRead(wrapped_body, 5, ASYNC),
rch8e6c6c42015-05-01 14:05:135802 MockRead(ASYNC, 0, 8),
[email protected]d9da5fe2010-10-13 22:37:165803 };
5804
Ryan Sleevib8d7ea02018-05-07 20:01:015805 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075806 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165807
[email protected]8ddf8322012-02-23 18:08:065808 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365809 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075810 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065811 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365812 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075813 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165814
[email protected]49639fa2011-12-20 23:22:415815 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165816
bnc691fda62016-08-12 00:43:165817 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015818 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165819
rch32320842015-05-16 15:57:095820 // Allow the SpdyProxyClientSocket's write callback to complete.
fdoray92e35a72016-06-10 15:54:555821 base::RunLoop().RunUntilIdle();
rch32320842015-05-16 15:57:095822 // Now allow the read of the response to complete.
mmenkee24011922015-12-17 22:12:595823 spdy_data.Resume();
[email protected]d9da5fe2010-10-13 22:37:165824 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015825 EXPECT_THAT(rv, IsOk());
[email protected]d9da5fe2010-10-13 22:37:165826
[email protected]58e32bb2013-01-21 18:23:255827 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:165828 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:255829 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
5830
bnc691fda62016-08-12 00:43:165831 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:525832 ASSERT_TRUE(response);
5833 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:025834 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d9da5fe2010-10-13 22:37:165835
5836 std::string response_data;
bnc691fda62016-08-12 00:43:165837 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]448d4ca52012-03-04 04:12:235838 EXPECT_EQ(kUploadData, response_data);
[email protected]d9da5fe2010-10-13 22:37:165839}
5840
5841// Test a SPDY CONNECT failure through an HTTPS Proxy.
bncd16676a2016-07-20 16:23:015842TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
[email protected]cb9bf6ca2011-01-28 13:15:275843 HttpRequestInfo request;
5844 request.method = "GET";
bncce36dca22015-04-21 22:11:235845 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:105846 request.traffic_annotation =
5847 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:275848
[email protected]d9da5fe2010-10-13 22:37:165849 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:495850 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
5851 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:515852 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:075853 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:095854 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d9da5fe2010-10-13 22:37:165855
bnc691fda62016-08-12 00:43:165856 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]d9da5fe2010-10-13 22:37:165857
bncce36dca22015-04-21 22:11:235858 // CONNECT to www.example.org:443 via SPDY
Ryan Hamilton0239aac2018-05-19 00:03:135859 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:045860 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
5861 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:135862 spdy::SpdySerializedFrame get(
5863 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]d9da5fe2010-10-13 22:37:165864
5865 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:415866 CreateMockWrite(connect, 0), CreateMockWrite(get, 2),
[email protected]d9da5fe2010-10-13 22:37:165867 };
5868
Ryan Hamilton0239aac2018-05-19 00:03:135869 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(1));
5870 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]d9da5fe2010-10-13 22:37:165871 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:415872 CreateMockRead(resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
[email protected]d9da5fe2010-10-13 22:37:165873 };
5874
Ryan Sleevib8d7ea02018-05-07 20:01:015875 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:075876 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d9da5fe2010-10-13 22:37:165877
[email protected]8ddf8322012-02-23 18:08:065878 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365879 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075880 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]8ddf8322012-02-23 18:08:065881 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:365882 ssl2.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:075883 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]d9da5fe2010-10-13 22:37:165884
[email protected]49639fa2011-12-20 23:22:415885 TestCompletionCallback callback1;
[email protected]d9da5fe2010-10-13 22:37:165886
bnc691fda62016-08-12 00:43:165887 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:015888 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]d9da5fe2010-10-13 22:37:165889
5890 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:015891 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]d9da5fe2010-10-13 22:37:165892
ttuttle960fcbf2016-04-19 13:26:325893 // TODO(juliatuttle): Anything else to check here?
[email protected]d9da5fe2010-10-13 22:37:165894}
5895
Matt Menkecb2cd0982018-12-19 17:54:045896// Test the case where a proxied H2 session doesn't exist when an auth challenge
5897// is observed, but does exist by the time auth credentials are provided.
5898// Proxy-Connection: Close is used so that there's a second DNS lookup, which is
5899// what causes the existing H2 session to be noticed and reused.
5900TEST_F(HttpNetworkTransactionTest, ProxiedH2SessionAppearsDuringAuth) {
5901 ProxyConfig proxy_config;
5902 proxy_config.set_auto_detect(true);
5903 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
5904
5905 CapturingProxyResolver capturing_proxy_resolver;
5906 capturing_proxy_resolver.set_proxy_server(
5907 ProxyServer(ProxyServer::SCHEME_HTTP, HostPortPair("myproxy", 70)));
5908 session_deps_.proxy_resolution_service =
5909 std::make_unique<ProxyResolutionService>(
5910 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
5911 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
5912 std::make_unique<CapturingProxyResolverFactory>(
5913 &capturing_proxy_resolver),
5914 nullptr);
5915
5916 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
5917
5918 const char kMyUrl[] = "https://www.example.org/";
5919 spdy::SpdySerializedFrame get(spdy_util_.ConstructSpdyGet(kMyUrl, 1, LOWEST));
5920 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:355921 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menkecb2cd0982018-12-19 17:54:045922 spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true));
5923
5924 spdy_util_.UpdateWithStreamDestruction(1);
5925 spdy::SpdySerializedFrame get2(
5926 spdy_util_.ConstructSpdyGet(kMyUrl, 3, LOWEST));
5927 spdy::SpdySerializedFrame get_resp2(
Raul Tambre94493c652019-03-11 17:18:355928 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Matt Menkecb2cd0982018-12-19 17:54:045929 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
5930
5931 MockWrite auth_challenge_writes[] = {
5932 MockWrite(ASYNC, 0,
5933 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5934 "Host: www.example.org:443\r\n"
5935 "Proxy-Connection: keep-alive\r\n\r\n"),
5936 };
5937
5938 MockRead auth_challenge_reads[] = {
5939 MockRead(ASYNC, 1,
5940 "HTTP/1.1 407 Authentication Required\r\n"
5941 "Content-Length: 0\r\n"
5942 "Proxy-Connection: close\r\n"
5943 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n\r\n"),
5944 };
5945
5946 MockWrite spdy_writes[] = {
5947 MockWrite(ASYNC, 0,
5948 "CONNECT www.example.org:443 HTTP/1.1\r\n"
5949 "Host: www.example.org:443\r\n"
5950 "Proxy-Connection: keep-alive\r\n"
5951 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
5952 CreateMockWrite(get, 2),
5953 CreateMockWrite(get2, 5),
5954 };
5955
5956 MockRead spdy_reads[] = {
5957 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n\r\n"),
5958 CreateMockRead(get_resp, 3, ASYNC),
5959 CreateMockRead(body, 4, ASYNC),
5960 CreateMockRead(get_resp2, 6, ASYNC),
5961 CreateMockRead(body2, 7, ASYNC),
5962
5963 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 8),
5964 };
5965
5966 SequencedSocketData auth_challenge1(auth_challenge_reads,
5967 auth_challenge_writes);
5968 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge1);
5969
5970 SequencedSocketData auth_challenge2(auth_challenge_reads,
5971 auth_challenge_writes);
5972 session_deps_.socket_factory->AddSocketDataProvider(&auth_challenge2);
5973
5974 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
5975 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
5976
5977 SSLSocketDataProvider ssl(ASYNC, OK);
5978 ssl.next_proto = kProtoHTTP2;
5979 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
5980
5981 TestCompletionCallback callback;
5982 std::string response_data;
5983
5984 // Run first request until an auth challenge is observed.
5985 HttpRequestInfo request1;
5986 request1.method = "GET";
5987 request1.url = GURL(kMyUrl);
5988 request1.traffic_annotation =
5989 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5990 HttpNetworkTransaction trans1(LOWEST, session.get());
5991 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
5992 EXPECT_THAT(callback.GetResult(rv), IsOk());
5993 const HttpResponseInfo* response = trans1.GetResponseInfo();
5994 ASSERT_TRUE(response);
5995 ASSERT_TRUE(response->headers);
5996 EXPECT_EQ(407, response->headers->response_code());
5997 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:585998 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
Matt Menkecb2cd0982018-12-19 17:54:045999
6000 // Run second request until an auth challenge is observed.
6001 HttpRequestInfo request2;
6002 request2.method = "GET";
6003 request2.url = GURL(kMyUrl);
6004 request2.traffic_annotation =
6005 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6006 HttpNetworkTransaction trans2(LOWEST, session.get());
6007 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6008 EXPECT_THAT(callback.GetResult(rv), IsOk());
6009 response = trans2.GetResponseInfo();
6010 ASSERT_TRUE(response);
6011 ASSERT_TRUE(response->headers);
6012 EXPECT_EQ(407, response->headers->response_code());
6013 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:586014 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
Matt Menkecb2cd0982018-12-19 17:54:046015
6016 // Now provide credentials for the first request, and wait for it to complete.
6017 rv = trans1.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6018 rv = callback.GetResult(rv);
6019 EXPECT_THAT(rv, IsOk());
6020 response = trans1.GetResponseInfo();
6021 ASSERT_TRUE(response);
6022 ASSERT_TRUE(response->headers);
6023 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6024 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6025 EXPECT_EQ(kUploadData, response_data);
6026
6027 // Now provide credentials for the second request. It should notice the
6028 // existing session, and reuse it.
6029 rv = trans2.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
6030 EXPECT_THAT(callback.GetResult(rv), IsOk());
6031 response = trans2.GetResponseInfo();
6032 ASSERT_TRUE(response);
6033 ASSERT_TRUE(response->headers);
6034 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6035 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6036 EXPECT_EQ(kUploadData, response_data);
6037}
6038
[email protected]f6c63db52013-02-02 00:35:226039// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6040// HTTPS Proxy to different servers.
bncd16676a2016-07-20 16:23:016041TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226042 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
6043 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496044 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6045 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516046 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076047 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096048 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506049 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226050
6051 HttpRequestInfo request1;
6052 request1.method = "GET";
bncce36dca22015-04-21 22:11:236053 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226054 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106055 request1.traffic_annotation =
6056 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226057
6058 HttpRequestInfo request2;
6059 request2.method = "GET";
bncce36dca22015-04-21 22:11:236060 request2.url = GURL("https://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226061 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106062 request2.traffic_annotation =
6063 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226064
bncce36dca22015-04-21 22:11:236065 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136066 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046067 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6068 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136069 spdy::SpdySerializedFrame conn_resp1(
Raul Tambre94493c652019-03-11 17:18:356070 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226071
bncce36dca22015-04-21 22:11:236072 // Fetch https://www.example.org/ via HTTP.
6073 const char get1[] =
6074 "GET / HTTP/1.1\r\n"
6075 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226076 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136077 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196078 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226079 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6080 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136081 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196082 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136083 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196084 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136085 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416086 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226087
bncce36dca22015-04-21 22:11:236088 // CONNECT to mail.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136089 spdy::SpdyHeaderBlock connect2_block;
6090 connect2_block[spdy::kHttp2MethodHeader] = "CONNECT";
6091 connect2_block[spdy::kHttp2AuthorityHeader] = "mail.example.org:443";
6092 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyHeaders(
Matt Menke6e879bd2019-03-18 17:26:046093 3, std::move(connect2_block), HttpProxyConnectJob::kH2QuicTunnelPriority,
6094 false));
[email protected]601e03f12014-04-06 16:26:396095
Ryan Hamilton0239aac2018-05-19 00:03:136096 spdy::SpdySerializedFrame conn_resp2(
Raul Tambre94493c652019-03-11 17:18:356097 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
[email protected]f6c63db52013-02-02 00:35:226098
bncce36dca22015-04-21 22:11:236099 // Fetch https://mail.example.org/ via HTTP.
6100 const char get2[] =
6101 "GET / HTTP/1.1\r\n"
6102 "Host: mail.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226103 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136104 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196105 spdy_util_.ConstructSpdyDataFrame(3, get2, false));
[email protected]f6c63db52013-02-02 00:35:226106 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6107 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136108 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196109 spdy_util_.ConstructSpdyDataFrame(3, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136110 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196111 spdy_util_.ConstructSpdyDataFrame(3, "22", false));
[email protected]f6c63db52013-02-02 00:35:226112
6113 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416114 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6115 CreateMockWrite(connect2, 5), CreateMockWrite(wrapped_get2, 7),
[email protected]f6c63db52013-02-02 00:35:226116 };
6117
6118 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416119 CreateMockRead(conn_resp1, 1, ASYNC),
6120 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
6121 CreateMockRead(wrapped_body1, 4, ASYNC),
6122 CreateMockRead(conn_resp2, 6, ASYNC),
6123 CreateMockRead(wrapped_get_resp2, 8, ASYNC),
6124 CreateMockRead(wrapped_body2, 9, ASYNC),
6125 MockRead(ASYNC, 0, 10),
[email protected]f6c63db52013-02-02 00:35:226126 };
6127
Ryan Sleevib8d7ea02018-05-07 20:01:016128 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506129 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226130
6131 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366132 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506133 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226134 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506135 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226136 SSLSocketDataProvider ssl3(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506137 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
[email protected]f6c63db52013-02-02 00:35:226138
6139 TestCompletionCallback callback;
6140
bnc691fda62016-08-12 00:43:166141 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206142 int rv = trans.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016143 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226144
6145 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166146 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]f6c63db52013-02-02 00:35:226147 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6148
bnc691fda62016-08-12 00:43:166149 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526150 ASSERT_TRUE(response);
6151 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226152 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6153
6154 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446155 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
bnc691fda62016-08-12 00:43:166156 rv = trans.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506157 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226158
bnc691fda62016-08-12 00:43:166159 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206160 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016161 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226162
6163 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166164 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226165 // Even though the SPDY connection is reused, a new tunnelled connection has
6166 // to be created, so the socket's load timing looks like a fresh connection.
6167 TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
6168
6169 // The requests should have different IDs, since they each are using their own
6170 // separate stream.
6171 EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6172
bnc691fda62016-08-12 00:43:166173 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506174 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226175}
6176
6177// Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
6178// HTTPS Proxy to the same server.
bncd16676a2016-07-20 16:23:016179TEST_F(HttpNetworkTransactionTest,
[email protected]f6c63db52013-02-02 00:35:226180 HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
6181 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496182 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6183 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516184 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076185 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096186 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506187 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226188
6189 HttpRequestInfo request1;
6190 request1.method = "GET";
bncce36dca22015-04-21 22:11:236191 request1.url = GURL("https://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226192 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106193 request1.traffic_annotation =
6194 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226195
6196 HttpRequestInfo request2;
6197 request2.method = "GET";
bncce36dca22015-04-21 22:11:236198 request2.url = GURL("https://www.example.org/2");
[email protected]f6c63db52013-02-02 00:35:226199 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106200 request2.traffic_annotation =
6201 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226202
bncce36dca22015-04-21 22:11:236203 // CONNECT to www.example.org:443 via SPDY.
Ryan Hamilton0239aac2018-05-19 00:03:136204 spdy::SpdySerializedFrame connect1(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046205 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6206 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:136207 spdy::SpdySerializedFrame conn_resp1(
Raul Tambre94493c652019-03-11 17:18:356208 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]f6c63db52013-02-02 00:35:226209
bncce36dca22015-04-21 22:11:236210 // Fetch https://www.example.org/ via HTTP.
6211 const char get1[] =
6212 "GET / HTTP/1.1\r\n"
6213 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226214 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136215 spdy::SpdySerializedFrame wrapped_get1(
Bence Békyd74f4382018-02-20 18:26:196216 spdy_util_.ConstructSpdyDataFrame(1, get1, false));
[email protected]f6c63db52013-02-02 00:35:226217 const char resp1[] = "HTTP/1.1 200 OK\r\n"
6218 "Content-Length: 1\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136219 spdy::SpdySerializedFrame wrapped_get_resp1(
Bence Békyd74f4382018-02-20 18:26:196220 spdy_util_.ConstructSpdyDataFrame(1, resp1, false));
Ryan Hamilton0239aac2018-05-19 00:03:136221 spdy::SpdySerializedFrame wrapped_body1(
Bence Békyd74f4382018-02-20 18:26:196222 spdy_util_.ConstructSpdyDataFrame(1, "1", false));
Ryan Hamilton0239aac2018-05-19 00:03:136223 spdy::SpdySerializedFrame window_update(
bncdf80d44fd2016-07-15 20:27:416224 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1.size()));
[email protected]f6c63db52013-02-02 00:35:226225
bncce36dca22015-04-21 22:11:236226 // Fetch https://www.example.org/2 via HTTP.
6227 const char get2[] =
6228 "GET /2 HTTP/1.1\r\n"
6229 "Host: www.example.org\r\n"
[email protected]f6c63db52013-02-02 00:35:226230 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136231 spdy::SpdySerializedFrame wrapped_get2(
Bence Békyd74f4382018-02-20 18:26:196232 spdy_util_.ConstructSpdyDataFrame(1, get2, false));
[email protected]f6c63db52013-02-02 00:35:226233 const char resp2[] = "HTTP/1.1 200 OK\r\n"
6234 "Content-Length: 2\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:136235 spdy::SpdySerializedFrame wrapped_get_resp2(
Bence Békyd74f4382018-02-20 18:26:196236 spdy_util_.ConstructSpdyDataFrame(1, resp2, false));
Ryan Hamilton0239aac2018-05-19 00:03:136237 spdy::SpdySerializedFrame wrapped_body2(
Bence Békyd74f4382018-02-20 18:26:196238 spdy_util_.ConstructSpdyDataFrame(1, "22", false));
[email protected]f6c63db52013-02-02 00:35:226239
6240 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416241 CreateMockWrite(connect1, 0), CreateMockWrite(wrapped_get1, 2),
6242 CreateMockWrite(wrapped_get2, 5),
[email protected]f6c63db52013-02-02 00:35:226243 };
6244
6245 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416246 CreateMockRead(conn_resp1, 1, ASYNC),
6247 CreateMockRead(wrapped_get_resp1, 3, ASYNC),
bnceb9aa7112017-01-05 01:03:466248 CreateMockRead(wrapped_body1, 4, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416249 CreateMockRead(wrapped_get_resp2, 6, ASYNC),
bnceb9aa7112017-01-05 01:03:466250 CreateMockRead(wrapped_body2, 7, SYNCHRONOUS),
bncdf80d44fd2016-07-15 20:27:416251 MockRead(ASYNC, 0, 8),
[email protected]f6c63db52013-02-02 00:35:226252 };
6253
Ryan Sleevib8d7ea02018-05-07 20:01:016254 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506255 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226256
6257 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366258 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506259 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226260 SSLSocketDataProvider ssl2(ASYNC, OK);
mmenke11eb5152015-06-09 14:50:506261 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]f6c63db52013-02-02 00:35:226262
6263 TestCompletionCallback callback;
6264
bnc87dcefc2017-05-25 12:47:586265 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196266 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206267 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016268 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226269
6270 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016271 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226272
6273 LoadTimingInfo load_timing_info;
6274 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6275 TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
6276
6277 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526278 ASSERT_TRUE(response);
6279 ASSERT_TRUE(response->headers);
[email protected]f6c63db52013-02-02 00:35:226280 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6281
6282 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446283 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
[email protected]90499482013-06-01 00:39:506284 EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226285 trans.reset();
6286
bnc87dcefc2017-05-25 12:47:586287 auto trans2 =
Jeremy Roman0579ed62017-08-29 15:56:196288 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206289 rv = trans2->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016290 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f6c63db52013-02-02 00:35:226291
[email protected]f6c63db52013-02-02 00:35:226292 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:016293 EXPECT_THAT(rv, IsOk());
[email protected]f6c63db52013-02-02 00:35:226294
6295 LoadTimingInfo load_timing_info2;
6296 EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
6297 TestLoadTimingReused(load_timing_info2);
6298
6299 // The requests should have the same ID.
6300 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6301
[email protected]90499482013-06-01 00:39:506302 EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
[email protected]f6c63db52013-02-02 00:35:226303}
6304
6305// Test load timing in the case of of two HTTP requests through a SPDY HTTPS
6306// Proxy to different servers.
bncd16676a2016-07-20 16:23:016307TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyLoadTimingTwoHttpRequests) {
[email protected]f6c63db52013-02-02 00:35:226308 // Configure against https proxy server "proxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496309 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6310 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516311 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076312 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096313 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:506314 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]f6c63db52013-02-02 00:35:226315
6316 HttpRequestInfo request1;
6317 request1.method = "GET";
bncce36dca22015-04-21 22:11:236318 request1.url = GURL("http://www.example.org/");
[email protected]f6c63db52013-02-02 00:35:226319 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106320 request1.traffic_annotation =
6321 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226322
6323 HttpRequestInfo request2;
6324 request2.method = "GET";
bncce36dca22015-04-21 22:11:236325 request2.url = GURL("http://mail.example.org/");
[email protected]f6c63db52013-02-02 00:35:226326 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:106327 request2.traffic_annotation =
6328 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f6c63db52013-02-02 00:35:226329
bncce36dca22015-04-21 22:11:236330 // http://www.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136331 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:236332 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136333 spdy::SpdySerializedFrame get1(
bnc42331402016-07-25 13:36:156334 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136335 spdy::SpdySerializedFrame get_resp1(
Raul Tambre94493c652019-03-11 17:18:356336 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:136337 spdy::SpdySerializedFrame body1(
6338 spdy_util_.ConstructSpdyDataFrame(1, "1", true));
rdsmithebb50aa2015-11-12 03:44:386339 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]f6c63db52013-02-02 00:35:226340
bncce36dca22015-04-21 22:11:236341 // http://mail.example.org/
Ryan Hamilton0239aac2018-05-19 00:03:136342 spdy::SpdyHeaderBlock headers2(
bncce36dca22015-04-21 22:11:236343 spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:136344 spdy::SpdySerializedFrame get2(
bnc42331402016-07-25 13:36:156345 spdy_util_.ConstructSpdyHeaders(3, std::move(headers2), LOWEST, true));
Ryan Hamilton0239aac2018-05-19 00:03:136346 spdy::SpdySerializedFrame get_resp2(
Raul Tambre94493c652019-03-11 17:18:356347 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:136348 spdy::SpdySerializedFrame body2(
6349 spdy_util_.ConstructSpdyDataFrame(3, "22", true));
[email protected]f6c63db52013-02-02 00:35:226350
6351 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:416352 CreateMockWrite(get1, 0), CreateMockWrite(get2, 3),
[email protected]f6c63db52013-02-02 00:35:226353 };
6354
6355 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:416356 CreateMockRead(get_resp1, 1, ASYNC),
6357 CreateMockRead(body1, 2, ASYNC),
6358 CreateMockRead(get_resp2, 4, ASYNC),
6359 CreateMockRead(body2, 5, ASYNC),
6360 MockRead(ASYNC, 0, 6),
[email protected]f6c63db52013-02-02 00:35:226361 };
6362
Ryan Sleevib8d7ea02018-05-07 20:01:016363 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
mmenke11eb5152015-06-09 14:50:506364 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]f6c63db52013-02-02 00:35:226365
6366 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:366367 ssl.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:506368 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]f6c63db52013-02-02 00:35:226369
6370 TestCompletionCallback callback;
6371
bnc87dcefc2017-05-25 12:47:586372 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:196373 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206374 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016375 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226376
6377 LoadTimingInfo load_timing_info;
6378 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
6379 TestLoadTimingNotReused(load_timing_info,
6380 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6381
6382 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:526383 ASSERT_TRUE(response);
6384 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:026385 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]f6c63db52013-02-02 00:35:226386
6387 std::string response_data;
Victor Costan9c7302b2018-08-27 16:39:446388 scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBuffer>(256);
mmenke11eb5152015-06-09 14:50:506389 rv = trans->Read(buf.get(), 256, callback.callback());
6390 EXPECT_EQ(1, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226391 // Delete the first request, so the second one can reuse the socket.
6392 trans.reset();
6393
bnc691fda62016-08-12 00:43:166394 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:206395 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016396 EXPECT_THAT(callback.GetResult(rv), IsOk());
[email protected]f6c63db52013-02-02 00:35:226397
6398 LoadTimingInfo load_timing_info2;
bnc691fda62016-08-12 00:43:166399 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
[email protected]f6c63db52013-02-02 00:35:226400 TestLoadTimingReused(load_timing_info2);
6401
6402 // The requests should have the same ID.
6403 EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
6404
bnc691fda62016-08-12 00:43:166405 rv = trans2.Read(buf.get(), 256, callback.callback());
mmenke11eb5152015-06-09 14:50:506406 EXPECT_EQ(2, callback.GetResult(rv));
[email protected]f6c63db52013-02-02 00:35:226407}
6408
Matt Menke2436b2f2018-12-11 18:07:116409// Test that an HTTP/2 CONNECT through an HTTPS Proxy to a HTTP/2 server and a
6410// direct (non-proxied) request to the proxy server are not pooled, as that
6411// would break socket pool isolation.
6412TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation1) {
6413 ProxyConfig proxy_config;
6414 proxy_config.set_auto_detect(true);
6415 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6416
6417 CapturingProxyResolver capturing_proxy_resolver;
6418 session_deps_.proxy_resolution_service =
6419 std::make_unique<ProxyResolutionService>(
6420 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6421 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6422 std::make_unique<CapturingProxyResolverFactory>(
6423 &capturing_proxy_resolver),
6424 nullptr);
6425
6426 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6427
6428 SpdyTestUtil spdy_util1;
6429 // CONNECT to www.example.org:443 via HTTP/2.
6430 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046431 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6432 HostPortPair("www.example.org", 443)));
Matt Menke2436b2f2018-12-11 18:07:116433 // fetch https://www.example.org/ via HTTP/2.
6434 const char kMyUrl[] = "https://www.example.org/";
6435 spdy::SpdySerializedFrame get(spdy_util1.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6436 spdy::SpdySerializedFrame wrapped_get(
6437 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6438 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:356439 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menke2436b2f2018-12-11 18:07:116440 spdy::SpdySerializedFrame get_resp(
Raul Tambre94493c652019-03-11 17:18:356441 spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
Matt Menke2436b2f2018-12-11 18:07:116442 spdy::SpdySerializedFrame wrapped_get_resp(
6443 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6444 spdy::SpdySerializedFrame body(spdy_util1.ConstructSpdyDataFrame(1, true));
6445 spdy::SpdySerializedFrame wrapped_body(
6446 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6447 spdy::SpdySerializedFrame window_update_get_resp(
6448 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6449 spdy::SpdySerializedFrame window_update_body(
6450 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6451
6452 MockWrite spdy_writes1[] = {
6453 CreateMockWrite(connect, 0),
6454 CreateMockWrite(wrapped_get, 2),
6455 CreateMockWrite(window_update_get_resp, 6),
6456 CreateMockWrite(window_update_body, 7),
6457 };
6458
6459 MockRead spdy_reads1[] = {
6460 CreateMockRead(conn_resp, 1, ASYNC),
6461 MockRead(ASYNC, ERR_IO_PENDING, 3),
6462 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6463 CreateMockRead(wrapped_body, 5, ASYNC),
6464 MockRead(ASYNC, 0, 8),
6465 };
6466
6467 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6468 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6469
6470 // Fetch https://proxy:70/ via HTTP/2. Needs a new SpdyTestUtil, since it uses
6471 // a new pipe.
6472 SpdyTestUtil spdy_util2;
6473 spdy::SpdySerializedFrame req(
6474 spdy_util2.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6475 MockWrite spdy_writes2[] = {CreateMockWrite(req, 0)};
6476
6477 spdy::SpdySerializedFrame resp(
6478 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6479 spdy::SpdySerializedFrame data(spdy_util2.ConstructSpdyDataFrame(1, true));
6480 MockRead spdy_reads2[] = {
6481 CreateMockRead(resp, 1),
6482 CreateMockRead(data, 2),
6483 MockRead(ASYNC, 0, 3),
6484 };
6485 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6486 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6487
6488 SSLSocketDataProvider ssl(ASYNC, OK);
6489 ssl.next_proto = kProtoHTTP2;
6490 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6491 SSLSocketDataProvider ssl2(ASYNC, OK);
6492 ssl2.next_proto = kProtoHTTP2;
6493 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6494 SSLSocketDataProvider ssl3(ASYNC, OK);
6495 ssl3.next_proto = kProtoHTTP2;
6496 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6497
6498 TestCompletionCallback callback;
6499 std::string response_data;
6500
6501 // Make a request using proxy:70 as a HTTP/2 proxy.
6502 capturing_proxy_resolver.set_proxy_server(
6503 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6504 HttpRequestInfo request1;
6505 request1.method = "GET";
6506 request1.url = GURL("https://www.example.org/");
6507 request1.traffic_annotation =
6508 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6509
6510 HttpNetworkTransaction trans1(LOWEST, session.get());
6511 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
6512 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6513
6514 // Allow the SpdyProxyClientSocket's write callback to complete.
6515 base::RunLoop().RunUntilIdle();
6516 // Now allow the read of the response to complete.
6517 spdy_data1.Resume();
6518 rv = callback.WaitForResult();
6519 EXPECT_THAT(rv, IsOk());
6520
6521 const HttpResponseInfo* response = trans1.GetResponseInfo();
6522 ASSERT_TRUE(response);
6523 ASSERT_TRUE(response->headers);
6524 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
6525
6526 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6527 EXPECT_EQ(kUploadData, response_data);
6528 RunUntilIdle();
6529
6530 // Make a direct HTTP/2 request to proxy:70.
6531 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6532 HttpRequestInfo request2;
6533 request2.method = "GET";
6534 request2.url = GURL("https://proxy:70/");
6535 request2.traffic_annotation =
6536 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6537 HttpNetworkTransaction trans2(LOWEST, session.get());
6538 EXPECT_THAT(callback.GetResult(trans2.Start(&request2, callback.callback(),
6539 NetLogWithSource())),
6540 IsOk());
6541 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6542}
6543
6544// Same as above, but reverse request order, since the code to check for an
6545// existing session is different for tunnels and direct connections.
6546TEST_F(HttpNetworkTransactionTest, SpdyProxyIsolation2) {
6547 // Configure against https proxy server "myproxy:80".
6548 ProxyConfig proxy_config;
6549 proxy_config.set_auto_detect(true);
6550 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
6551
6552 CapturingProxyResolver capturing_proxy_resolver;
6553 session_deps_.proxy_resolution_service =
6554 std::make_unique<ProxyResolutionService>(
6555 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
6556 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
6557 std::make_unique<CapturingProxyResolverFactory>(
6558 &capturing_proxy_resolver),
6559 nullptr);
6560
6561 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
6562 // Fetch https://proxy:70/ via HTTP/2.
6563 SpdyTestUtil spdy_util1;
6564 spdy::SpdySerializedFrame req(
6565 spdy_util1.ConstructSpdyGet("https://proxy:70/", 1, LOWEST));
6566 MockWrite spdy_writes1[] = {CreateMockWrite(req, 0)};
6567
6568 spdy::SpdySerializedFrame resp(
6569 spdy_util1.ConstructSpdyGetReply(nullptr, 0, 1));
6570 spdy::SpdySerializedFrame data(spdy_util1.ConstructSpdyDataFrame(1, true));
6571 MockRead spdy_reads1[] = {
6572 CreateMockRead(resp, 1),
6573 CreateMockRead(data, 2),
6574 MockRead(ASYNC, 0, 3),
6575 };
6576 SequencedSocketData spdy_data1(spdy_reads1, spdy_writes1);
6577 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data1);
6578
6579 SpdyTestUtil spdy_util2;
6580 // CONNECT to www.example.org:443 via HTTP/2.
6581 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:046582 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
6583 HostPortPair("www.example.org", 443)));
Matt Menke2436b2f2018-12-11 18:07:116584 // fetch https://www.example.org/ via HTTP/2.
6585 const char kMyUrl[] = "https://www.example.org/";
6586 spdy::SpdySerializedFrame get(spdy_util2.ConstructSpdyGet(kMyUrl, 1, LOWEST));
6587 spdy::SpdySerializedFrame wrapped_get(
6588 spdy_util_.ConstructWrappedSpdyFrame(get, 1));
6589 spdy::SpdySerializedFrame conn_resp(
6590 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
6591 spdy::SpdySerializedFrame get_resp(
6592 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
6593 spdy::SpdySerializedFrame wrapped_get_resp(
6594 spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
6595 spdy::SpdySerializedFrame body(spdy_util2.ConstructSpdyDataFrame(1, true));
6596 spdy::SpdySerializedFrame wrapped_body(
6597 spdy_util_.ConstructWrappedSpdyFrame(body, 1));
6598 spdy::SpdySerializedFrame window_update_get_resp(
6599 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp.size()));
6600 spdy::SpdySerializedFrame window_update_body(
6601 spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body.size()));
6602
6603 MockWrite spdy_writes2[] = {
6604 CreateMockWrite(connect, 0),
6605 CreateMockWrite(wrapped_get, 2),
6606 CreateMockWrite(window_update_get_resp, 6),
6607 CreateMockWrite(window_update_body, 7),
6608 };
6609
6610 MockRead spdy_reads2[] = {
6611 CreateMockRead(conn_resp, 1, ASYNC),
6612 MockRead(ASYNC, ERR_IO_PENDING, 3),
6613 CreateMockRead(wrapped_get_resp, 4, ASYNC),
6614 CreateMockRead(wrapped_body, 5, ASYNC),
6615 MockRead(ASYNC, 0, 8),
6616 };
6617
6618 SequencedSocketData spdy_data2(spdy_reads2, spdy_writes2);
6619 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data2);
6620
6621 SSLSocketDataProvider ssl(ASYNC, OK);
6622 ssl.next_proto = kProtoHTTP2;
6623 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
6624 SSLSocketDataProvider ssl2(ASYNC, OK);
6625 ssl2.next_proto = kProtoHTTP2;
6626 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
6627 SSLSocketDataProvider ssl3(ASYNC, OK);
6628 ssl3.next_proto = kProtoHTTP2;
6629 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
6630
6631 TestCompletionCallback callback;
6632 std::string response_data;
6633
6634 // Make a direct HTTP/2 request to proxy:70.
6635 capturing_proxy_resolver.set_proxy_server(ProxyServer::Direct());
6636 HttpRequestInfo request1;
6637 request1.method = "GET";
6638 request1.url = GURL("https://proxy:70/");
6639 request1.traffic_annotation =
6640 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6641 HttpNetworkTransaction trans1(LOWEST, session.get());
6642 EXPECT_THAT(callback.GetResult(trans1.Start(&request1, callback.callback(),
6643 NetLogWithSource())),
6644 IsOk());
6645 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
6646 RunUntilIdle();
6647
6648 // Make a request using proxy:70 as a HTTP/2 proxy.
6649 capturing_proxy_resolver.set_proxy_server(
6650 ProxyServer(ProxyServer::SCHEME_HTTPS, HostPortPair("proxy", 70)));
6651 HttpRequestInfo request2;
6652 request2.method = "GET";
6653 request2.url = GURL("https://www.example.org/");
6654 request2.traffic_annotation =
6655 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6656
6657 HttpNetworkTransaction trans2(LOWEST, session.get());
6658 int rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
6659 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
6660
6661 // Allow the SpdyProxyClientSocket's write callback to complete.
6662 base::RunLoop().RunUntilIdle();
6663 // Now allow the read of the response to complete.
6664 spdy_data2.Resume();
6665 rv = callback.WaitForResult();
6666 EXPECT_THAT(rv, IsOk());
6667
6668 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
6669 ASSERT_TRUE(response2);
6670 ASSERT_TRUE(response2->headers);
6671 EXPECT_EQ("HTTP/1.1 200", response2->headers->GetStatusLine());
6672
6673 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
6674 EXPECT_EQ(kUploadData, response_data);
6675}
6676
[email protected]2df19bb2010-08-25 20:13:466677// Test the challenge-response-retry sequence through an HTTPS Proxy
bncd16676a2016-07-20 16:23:016678TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
[email protected]2df19bb2010-08-25 20:13:466679 HttpRequestInfo request;
6680 request.method = "GET";
bncce36dca22015-04-21 22:11:236681 request.url = GURL("http://www.example.org/");
[email protected]2df19bb2010-08-25 20:13:466682 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:296683 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:106684 request.traffic_annotation =
6685 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:466686
[email protected]79cb5c12011-09-12 13:12:046687 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496688 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6689 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:516690 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:076691 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:096692 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276693
[email protected]2df19bb2010-08-25 20:13:466694 // Since we have proxy, should use full url
6695 MockWrite data_writes1[] = {
bnc691fda62016-08-12 00:43:166696 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6697 "Host: www.example.org\r\n"
6698 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466699
bnc691fda62016-08-12 00:43:166700 // After calling trans.RestartWithAuth(), this is the request we should
bncce36dca22015-04-21 22:11:236701 // be issuing -- the final header line contains the credentials.
bnc691fda62016-08-12 00:43:166702 MockWrite("GET http://www.example.org/ HTTP/1.1\r\n"
6703 "Host: www.example.org\r\n"
6704 "Proxy-Connection: keep-alive\r\n"
6705 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:466706 };
6707
6708 // The proxy responds to the GET with a 407, using a persistent
6709 // connection.
6710 MockRead data_reads1[] = {
6711 // No credentials.
6712 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
6713 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
6714 MockRead("Proxy-Connection: keep-alive\r\n"),
6715 MockRead("Content-Length: 0\r\n\r\n"),
6716
6717 MockRead("HTTP/1.1 200 OK\r\n"),
6718 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
6719 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:066720 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:466721 };
6722
Ryan Sleevib8d7ea02018-05-07 20:01:016723 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:076724 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:066725 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:076726 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:466727
[email protected]49639fa2011-12-20 23:22:416728 TestCompletionCallback callback1;
[email protected]2df19bb2010-08-25 20:13:466729
bnc691fda62016-08-12 00:43:166730 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506731
bnc691fda62016-08-12 00:43:166732 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:016733 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466734
6735 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:016736 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466737
[email protected]58e32bb2013-01-21 18:23:256738 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:166739 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256740 TestLoadTimingNotReused(load_timing_info,
6741 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
6742
bnc691fda62016-08-12 00:43:166743 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526744 ASSERT_TRUE(response);
6745 ASSERT_TRUE(response->headers);
[email protected]2df19bb2010-08-25 20:13:466746 EXPECT_EQ(407, response->headers->response_code());
6747 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:586748 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge));
Wojciech Dzierżanowski0950c372019-04-02 19:29:506749 EXPECT_FALSE(response->did_use_http_auth);
[email protected]2df19bb2010-08-25 20:13:466750
[email protected]49639fa2011-12-20 23:22:416751 TestCompletionCallback callback2;
[email protected]2df19bb2010-08-25 20:13:466752
bnc691fda62016-08-12 00:43:166753 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:016754 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:466755
6756 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:016757 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:466758
[email protected]58e32bb2013-01-21 18:23:256759 load_timing_info = LoadTimingInfo();
bnc691fda62016-08-12 00:43:166760 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]58e32bb2013-01-21 18:23:256761 // Retrying with HTTP AUTH is considered to be reusing a socket.
6762 TestLoadTimingReused(load_timing_info);
6763
bnc691fda62016-08-12 00:43:166764 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:526765 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:466766
6767 EXPECT_TRUE(response->headers->IsKeepAlive());
6768 EXPECT_EQ(200, response->headers->response_code());
6769 EXPECT_EQ(100, response->headers->GetContentLength());
6770 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Wojciech Dzierżanowski0950c372019-04-02 19:29:506771 EXPECT_TRUE(response->did_use_http_auth);
[email protected]2df19bb2010-08-25 20:13:466772
6773 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:586774 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]2df19bb2010-08-25 20:13:466775}
6776
[email protected]23e482282013-06-14 16:08:026777void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
[email protected]c744cf22009-02-27 07:28:086778 const MockRead& status, int expected_status) {
[email protected]1c773ea12009-04-28 19:58:426779 HttpRequestInfo request;
[email protected]c744cf22009-02-27 07:28:086780 request.method = "GET";
bncce36dca22015-04-21 22:11:236781 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106782 request.traffic_annotation =
6783 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c744cf22009-02-27 07:28:086784
[email protected]cb9bf6ca2011-01-28 13:15:276785 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:496786 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
6787 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:096788 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:276789
[email protected]c744cf22009-02-27 07:28:086790 // Since we have proxy, should try to establish tunnel.
6791 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:176792 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
6793 "Host: www.example.org:443\r\n"
6794 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]c744cf22009-02-27 07:28:086795 };
6796
6797 MockRead data_reads[] = {
mmenked39192ee2015-12-09 00:57:236798 status, MockRead("Content-Length: 10\r\n\r\n"),
6799 // No response body because the test stops reading here.
6800 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]c744cf22009-02-27 07:28:086801 };
6802
Ryan Sleevib8d7ea02018-05-07 20:01:016803 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:076804 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]c744cf22009-02-27 07:28:086805
[email protected]49639fa2011-12-20 23:22:416806 TestCompletionCallback callback;
[email protected]c744cf22009-02-27 07:28:086807
bnc691fda62016-08-12 00:43:166808 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:506809
tfarina42834112016-09-22 13:38:206810 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:016811 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]c744cf22009-02-27 07:28:086812
6813 rv = callback.WaitForResult();
6814 EXPECT_EQ(expected_status, rv);
6815}
6816
[email protected]23e482282013-06-14 16:08:026817void HttpNetworkTransactionTest::ConnectStatusHelper(
[email protected]448d4ca52012-03-04 04:12:236818 const MockRead& status) {
[email protected]c744cf22009-02-27 07:28:086819 ConnectStatusHelperWithExpectedStatus(
[email protected]1c773ea12009-04-28 19:58:426820 status, ERR_TUNNEL_CONNECTION_FAILED);
[email protected]c744cf22009-02-27 07:28:086821}
6822
bncd16676a2016-07-20 16:23:016823TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
[email protected]c744cf22009-02-27 07:28:086824 ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
6825}
6826
bncd16676a2016-07-20 16:23:016827TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
[email protected]c744cf22009-02-27 07:28:086828 ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
6829}
6830
bncd16676a2016-07-20 16:23:016831TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
[email protected]c744cf22009-02-27 07:28:086832 ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
6833}
6834
bncd16676a2016-07-20 16:23:016835TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
[email protected]c744cf22009-02-27 07:28:086836 ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
6837}
6838
bncd16676a2016-07-20 16:23:016839TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
[email protected]c744cf22009-02-27 07:28:086840 ConnectStatusHelper(
6841 MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
6842}
6843
bncd16676a2016-07-20 16:23:016844TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
[email protected]c744cf22009-02-27 07:28:086845 ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
6846}
6847
bncd16676a2016-07-20 16:23:016848TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
[email protected]c744cf22009-02-27 07:28:086849 ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
6850}
6851
bncd16676a2016-07-20 16:23:016852TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
[email protected]c744cf22009-02-27 07:28:086853 ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
6854}
6855
bncd16676a2016-07-20 16:23:016856TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
[email protected]c744cf22009-02-27 07:28:086857 ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
6858}
6859
bncd16676a2016-07-20 16:23:016860TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
[email protected]c744cf22009-02-27 07:28:086861 ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
6862}
6863
bncd16676a2016-07-20 16:23:016864TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
[email protected]c744cf22009-02-27 07:28:086865 ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
6866}
6867
bncd16676a2016-07-20 16:23:016868TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
[email protected]c744cf22009-02-27 07:28:086869 ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
6870}
6871
bncd16676a2016-07-20 16:23:016872TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
[email protected]c744cf22009-02-27 07:28:086873 ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
6874}
6875
bncd16676a2016-07-20 16:23:016876TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
[email protected]c744cf22009-02-27 07:28:086877 ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
6878}
6879
bncd16676a2016-07-20 16:23:016880TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
[email protected]c744cf22009-02-27 07:28:086881 ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
6882}
6883
bncd16676a2016-07-20 16:23:016884TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
[email protected]c744cf22009-02-27 07:28:086885 ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
6886}
6887
bncd16676a2016-07-20 16:23:016888TEST_F(HttpNetworkTransactionTest, ConnectStatus308) {
[email protected]0a17aab32014-04-24 03:32:376889 ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
6890}
6891
bncd16676a2016-07-20 16:23:016892TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
[email protected]c744cf22009-02-27 07:28:086893 ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
6894}
6895
bncd16676a2016-07-20 16:23:016896TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
[email protected]c744cf22009-02-27 07:28:086897 ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
6898}
6899
bncd16676a2016-07-20 16:23:016900TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
[email protected]c744cf22009-02-27 07:28:086901 ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
6902}
6903
bncd16676a2016-07-20 16:23:016904TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
[email protected]c744cf22009-02-27 07:28:086905 ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
6906}
6907
bncd16676a2016-07-20 16:23:016908TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
[email protected]c744cf22009-02-27 07:28:086909 ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
6910}
6911
bncd16676a2016-07-20 16:23:016912TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
[email protected]c744cf22009-02-27 07:28:086913 ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
6914}
6915
bncd16676a2016-07-20 16:23:016916TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
[email protected]c744cf22009-02-27 07:28:086917 ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
6918}
6919
bncd16676a2016-07-20 16:23:016920TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
[email protected]c744cf22009-02-27 07:28:086921 ConnectStatusHelperWithExpectedStatus(
6922 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
[email protected]a7ea8832010-07-12 17:54:546923 ERR_PROXY_AUTH_UNSUPPORTED);
[email protected]c744cf22009-02-27 07:28:086924}
6925
bncd16676a2016-07-20 16:23:016926TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
[email protected]c744cf22009-02-27 07:28:086927 ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
6928}
6929
bncd16676a2016-07-20 16:23:016930TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
[email protected]c744cf22009-02-27 07:28:086931 ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
6932}
6933
bncd16676a2016-07-20 16:23:016934TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
[email protected]c744cf22009-02-27 07:28:086935 ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
6936}
6937
bncd16676a2016-07-20 16:23:016938TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
[email protected]c744cf22009-02-27 07:28:086939 ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
6940}
6941
bncd16676a2016-07-20 16:23:016942TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
[email protected]c744cf22009-02-27 07:28:086943 ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
6944}
6945
bncd16676a2016-07-20 16:23:016946TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
[email protected]c744cf22009-02-27 07:28:086947 ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
6948}
6949
bncd16676a2016-07-20 16:23:016950TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
[email protected]c744cf22009-02-27 07:28:086951 ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
6952}
6953
bncd16676a2016-07-20 16:23:016954TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
[email protected]c744cf22009-02-27 07:28:086955 ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
6956}
6957
bncd16676a2016-07-20 16:23:016958TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
[email protected]c744cf22009-02-27 07:28:086959 ConnectStatusHelper(
6960 MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
6961}
6962
bncd16676a2016-07-20 16:23:016963TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
[email protected]c744cf22009-02-27 07:28:086964 ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
6965}
6966
bncd16676a2016-07-20 16:23:016967TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
[email protected]c744cf22009-02-27 07:28:086968 ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
6969}
6970
bncd16676a2016-07-20 16:23:016971TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
[email protected]c744cf22009-02-27 07:28:086972 ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
6973}
6974
bncd16676a2016-07-20 16:23:016975TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
[email protected]c744cf22009-02-27 07:28:086976 ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
6977}
6978
bncd16676a2016-07-20 16:23:016979TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
[email protected]c744cf22009-02-27 07:28:086980 ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
6981}
6982
bncd16676a2016-07-20 16:23:016983TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
[email protected]c744cf22009-02-27 07:28:086984 ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
6985}
6986
bncd16676a2016-07-20 16:23:016987TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
[email protected]c744cf22009-02-27 07:28:086988 ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
6989}
6990
[email protected]038e9a32008-10-08 22:40:166991// Test the flow when both the proxy server AND origin server require
6992// authentication. Again, this uses basic auth for both since that is
6993// the simplest to mock.
bncd16676a2016-07-20 16:23:016994TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
[email protected]cb9bf6ca2011-01-28 13:15:276995 HttpRequestInfo request;
6996 request.method = "GET";
bncce36dca22015-04-21 22:11:236997 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:106998 request.traffic_annotation =
6999 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:277000
[email protected]038e9a32008-10-08 22:40:167001 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:497002 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
7003 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:097004 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3fe8d2f82013-10-17 08:56:077005
bnc691fda62016-08-12 00:43:167006 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]038e9a32008-10-08 22:40:167007
[email protected]f9ee6b52008-11-08 06:46:237008 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:237009 MockWrite(
7010 "GET http://www.example.org/ HTTP/1.1\r\n"
7011 "Host: www.example.org\r\n"
7012 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:237013 };
7014
[email protected]038e9a32008-10-08 22:40:167015 MockRead data_reads1[] = {
7016 MockRead("HTTP/1.0 407 Unauthorized\r\n"),
7017 // Give a couple authenticate options (only the middle one is actually
7018 // supported).
[email protected]22927ad2009-09-21 19:56:197019 MockRead("Proxy-Authenticate: Basic invalid\r\n"), // Malformed.
[email protected]038e9a32008-10-08 22:40:167020 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7021 MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
7022 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7023 // Large content-length -- won't matter, as connection will be reset.
7024 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067025 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]038e9a32008-10-08 22:40:167026 };
7027
bnc691fda62016-08-12 00:43:167028 // After calling trans.RestartWithAuth() the first time, this is the
[email protected]038e9a32008-10-08 22:40:167029 // request we should be issuing -- the final header line contains the
7030 // proxy's credentials.
7031 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:237032 MockWrite(
7033 "GET http://www.example.org/ HTTP/1.1\r\n"
7034 "Host: www.example.org\r\n"
7035 "Proxy-Connection: keep-alive\r\n"
7036 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167037 };
7038
7039 // Now the proxy server lets the request pass through to origin server.
7040 // The origin server responds with a 401.
7041 MockRead data_reads2[] = {
7042 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
7043 // Note: We are using the same realm-name as the proxy server. This is
7044 // completely valid, as realms are unique across hosts.
7045 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
7046 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7047 MockRead("Content-Length: 2000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067048 MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached.
[email protected]038e9a32008-10-08 22:40:167049 };
7050
bnc691fda62016-08-12 00:43:167051 // After calling trans.RestartWithAuth() the second time, we should send
[email protected]038e9a32008-10-08 22:40:167052 // the credentials for both the proxy and origin server.
7053 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:237054 MockWrite(
7055 "GET http://www.example.org/ HTTP/1.1\r\n"
7056 "Host: www.example.org\r\n"
7057 "Proxy-Connection: keep-alive\r\n"
7058 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
7059 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]038e9a32008-10-08 22:40:167060 };
7061
7062 // Lastly we get the desired content.
7063 MockRead data_reads3[] = {
7064 MockRead("HTTP/1.0 200 OK\r\n"),
7065 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
7066 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:067067 MockRead(SYNCHRONOUS, OK),
[email protected]038e9a32008-10-08 22:40:167068 };
7069
Ryan Sleevib8d7ea02018-05-07 20:01:017070 StaticSocketDataProvider data1(data_reads1, data_writes1);
7071 StaticSocketDataProvider data2(data_reads2, data_writes2);
7072 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077073 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7074 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7075 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]038e9a32008-10-08 22:40:167076
[email protected]49639fa2011-12-20 23:22:417077 TestCompletionCallback callback1;
[email protected]038e9a32008-10-08 22:40:167078
tfarina42834112016-09-22 13:38:207079 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017080 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167081
7082 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017083 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167084
bnc691fda62016-08-12 00:43:167085 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527086 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587087 EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge));
[email protected]038e9a32008-10-08 22:40:167088
[email protected]49639fa2011-12-20 23:22:417089 TestCompletionCallback callback2;
[email protected]038e9a32008-10-08 22:40:167090
bnc691fda62016-08-12 00:43:167091 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:017092 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167093
7094 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017095 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167096
bnc691fda62016-08-12 00:43:167097 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527098 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587099 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]038e9a32008-10-08 22:40:167100
[email protected]49639fa2011-12-20 23:22:417101 TestCompletionCallback callback3;
[email protected]038e9a32008-10-08 22:40:167102
bnc691fda62016-08-12 00:43:167103 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
7104 callback3.callback());
robpercival214763f2016-07-01 23:27:017105 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]038e9a32008-10-08 22:40:167106
7107 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017108 EXPECT_THAT(rv, IsOk());
[email protected]038e9a32008-10-08 22:40:167109
bnc691fda62016-08-12 00:43:167110 response = trans.GetResponseInfo();
Emily Starkf2c9bbd2019-04-09 17:08:587111 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]038e9a32008-10-08 22:40:167112 EXPECT_EQ(100, response->headers->GetContentLength());
[email protected]038e9a32008-10-08 22:40:167113}
[email protected]4ddaf2502008-10-23 18:26:197114
[email protected]ea9dc9a2009-09-05 00:43:327115// For the NTLM implementation using SSPI, we skip the NTLM tests since we
7116// can't hook into its internals to cause it to generate predictable NTLM
7117// authorization headers.
7118#if defined(NTLM_PORTABLE)
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377119// The NTLM authentication unit tests are based on known test data from the
7120// [MS-NLMP] Specification [1]. These tests are primarily of the authentication
7121// flow rather than the implementation of the NTLM protocol. See net/ntlm
7122// for the implementation and testing of the protocol.
7123//
7124// [1] https://msdn.microsoft.com/en-us/library/cc236621.aspx
[email protected]385a4672009-03-11 22:21:297125
7126// Enter the correct password and authenticate successfully.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557127TEST_F(HttpNetworkTransactionTest, NTLMAuthV2) {
[email protected]1c773ea12009-04-28 19:58:427128 HttpRequestInfo request;
[email protected]3f918782009-02-28 01:29:247129 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557130 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e62018-02-07 07:41:107131 request.traffic_annotation =
7132 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:547133
7134 // Ensure load is not disrupted by flags which suppress behaviour specific
7135 // to other auth schemes.
7136 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
[email protected]3f918782009-02-28 01:29:247137
Zentaro Kavanagh6ccee512017-09-28 18:34:097138 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7139 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097140 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277141
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377142 // Generate the NTLM messages based on known test data.
7143 std::string negotiate_msg;
7144 std::string challenge_msg;
7145 std::string authenticate_msg;
7146 base::Base64Encode(
7147 base::StringPiece(
7148 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247149 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377150 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557151 base::Base64Encode(
7152 base::StringPiece(
7153 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247154 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557155 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377156 base::Base64Encode(
7157 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097158 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557159 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247160 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557161 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377162 &authenticate_msg);
7163
[email protected]3f918782009-02-28 01:29:247164 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557165 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7166 "Host: server\r\n"
7167 "Connection: keep-alive\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247168 };
7169
7170 MockRead data_reads1[] = {
7171 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047172 // Negotiate and NTLM are often requested together. However, we only want
7173 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7174 // the header that requests Negotiate for this test.
[email protected]3f918782009-02-28 01:29:247175 MockRead("WWW-Authenticate: NTLM\r\n"),
7176 MockRead("Connection: close\r\n"),
7177 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367178 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247179 // Missing content -- won't matter, as connection will be reset.
[email protected]3f918782009-02-28 01:29:247180 };
7181
7182 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167183 // After restarting with a null identity, this is the
7184 // request we should be issuing -- the final header line contains a Type
7185 // 1 message.
7186 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557187 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167188 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377189 "Authorization: NTLM "),
7190 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247191
bnc691fda62016-08-12 00:43:167192 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377193 // (using correct credentials). The second request continues on the
7194 // same connection.
bnc691fda62016-08-12 00:43:167195 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557196 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167197 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377198 "Authorization: NTLM "),
7199 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]3f918782009-02-28 01:29:247200 };
7201
7202 MockRead data_reads2[] = {
Bence Béky1e4ef192017-09-18 19:58:027203 // The origin server responds with a Type 2 message.
7204 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377205 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7206 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027207 MockRead("Content-Type: text/html\r\n\r\n"),
7208 MockRead("You are not authorized to view this page\r\n"),
[email protected]3f918782009-02-28 01:29:247209
Bence Béky1e4ef192017-09-18 19:58:027210 // Lastly we get the desired content.
7211 MockRead("HTTP/1.1 200 OK\r\n"),
7212 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7213 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]3f918782009-02-28 01:29:247214 };
7215
Ryan Sleevib8d7ea02018-05-07 20:01:017216 StaticSocketDataProvider data1(data_reads1, data_writes1);
7217 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:077218 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7219 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3f918782009-02-28 01:29:247220
Bence Béky83eb3512017-09-05 12:56:097221 SSLSocketDataProvider ssl1(ASYNC, OK);
7222 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7223 SSLSocketDataProvider ssl2(ASYNC, OK);
7224 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7225
[email protected]49639fa2011-12-20 23:22:417226 TestCompletionCallback callback1;
[email protected]3f918782009-02-28 01:29:247227
bnc691fda62016-08-12 00:43:167228 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507229
tfarina42834112016-09-22 13:38:207230 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017231 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247232
7233 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017234 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247235
bnc691fda62016-08-12 00:43:167236 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227237
bnc691fda62016-08-12 00:43:167238 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527239 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587240 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
[email protected]3f918782009-02-28 01:29:247241
[email protected]49639fa2011-12-20 23:22:417242 TestCompletionCallback callback2;
[email protected]10af5fe72011-01-31 16:17:257243
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377244 rv = trans.RestartWithAuth(
7245 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7246 callback2.callback());
robpercival214763f2016-07-01 23:27:017247 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257248
7249 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017250 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257251
bnc691fda62016-08-12 00:43:167252 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257253
bnc691fda62016-08-12 00:43:167254 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527255 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587256 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]10af5fe72011-01-31 16:17:257257
[email protected]49639fa2011-12-20 23:22:417258 TestCompletionCallback callback3;
[email protected]3f918782009-02-28 01:29:247259
bnc691fda62016-08-12 00:43:167260 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017261 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3f918782009-02-28 01:29:247262
[email protected]0757e7702009-03-27 04:00:227263 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017264 EXPECT_THAT(rv, IsOk());
[email protected]3f918782009-02-28 01:29:247265
bnc691fda62016-08-12 00:43:167266 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527267 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587268 EXPECT_FALSE(response->auth_challenge.has_value());
Bence Béky1e4ef192017-09-18 19:58:027269 EXPECT_EQ(14, response->headers->GetContentLength());
7270
7271 std::string response_data;
7272 rv = ReadTransaction(&trans, &response_data);
7273 EXPECT_THAT(rv, IsOk());
7274 EXPECT_EQ("Please Login\r\n", response_data);
7275
7276 EXPECT_TRUE(data1.AllReadDataConsumed());
7277 EXPECT_TRUE(data1.AllWriteDataConsumed());
7278 EXPECT_TRUE(data2.AllReadDataConsumed());
7279 EXPECT_TRUE(data2.AllWriteDataConsumed());
[email protected]3f918782009-02-28 01:29:247280}
7281
[email protected]385a4672009-03-11 22:21:297282// Enter a wrong password, and then the correct one.
Zentaro Kavanagh1890a3d2018-01-29 19:52:557283TEST_F(HttpNetworkTransactionTest, NTLMAuthV2WrongThenRightPassword) {
[email protected]1c773ea12009-04-28 19:58:427284 HttpRequestInfo request;
[email protected]385a4672009-03-11 22:21:297285 request.method = "GET";
Zentaro Kavanagh1890a3d2018-01-29 19:52:557286 request.url = GURL("https://server/kids/login.aspx");
Ramin Halavatib5e433e62018-02-07 07:41:107287 request.traffic_annotation =
7288 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]385a4672009-03-11 22:21:297289
Zentaro Kavanagh6ccee512017-09-28 18:34:097290 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7291 MockGetMSTime, MockGenerateRandom, MockGetHostName);
danakj1fd259a02016-04-16 03:17:097292 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277293
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377294 // Generate the NTLM messages based on known test data.
7295 std::string negotiate_msg;
7296 std::string challenge_msg;
7297 std::string authenticate_msg;
7298 base::Base64Encode(
7299 base::StringPiece(
7300 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247301 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377302 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557303 base::Base64Encode(
7304 base::StringPiece(
7305 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247306 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557307 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377308 base::Base64Encode(
7309 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097310 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557311 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247312 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557313 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377314 &authenticate_msg);
7315
7316 // The authenticate message when |kWrongPassword| is sent.
7317 std::string wrong_password_authenticate_msg(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557318 "TlRMTVNTUAADAAAAGAAYAFgAAACKAIoAcAAAAAwADAD6AAAACAAIAAYBAAAQABAADgEAAAAA"
7319 "AABYAAAAA4IIAAAAAAAAAAAAAPknEYqtJQtusopDRSfYzAAAAAAAAAAAAAAAAAAAAAAAAAAA"
7320 "AAAAAOtVz38osnFdRRggUQHUJ3EBAQAAAAAAAIALyP0A1NIBqqqqqqqqqqoAAAAAAgAMAEQA"
7321 "bwBtAGEAaQBuAAEADABTAGUAcgB2AGUAcgAGAAQAAgAAAAoAEAAAAAAAAAAAAAAAAAAAAAAA"
7322 "CQAWAEgAVABUAFAALwBzAGUAcgB2AGUAcgAAAAAAAAAAAEQAbwBtAGEAaQBuAFUAcwBlAHIA"
7323 "QwBPAE0AUABVAFQARQBSAA==");
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377324
Zentaro Kavanagh1890a3d2018-01-29 19:52:557325 // Sanity check that it's the same length as the correct authenticate message
7326 // and that it's different.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377327 ASSERT_EQ(authenticate_msg.length(),
7328 wrong_password_authenticate_msg.length());
Zentaro Kavanagh1890a3d2018-01-29 19:52:557329 ASSERT_NE(authenticate_msg, wrong_password_authenticate_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377330
[email protected]385a4672009-03-11 22:21:297331 MockWrite data_writes1[] = {
Zentaro Kavanagh1890a3d2018-01-29 19:52:557332 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
7333 "Host: server\r\n"
7334 "Connection: keep-alive\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297335 };
7336
7337 MockRead data_reads1[] = {
7338 MockRead("HTTP/1.1 401 Access Denied\r\n"),
[email protected]aef04272010-06-28 18:03:047339 // Negotiate and NTLM are often requested together. However, we only want
7340 // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
7341 // the header that requests Negotiate for this test.
[email protected]385a4672009-03-11 22:21:297342 MockRead("WWW-Authenticate: NTLM\r\n"),
7343 MockRead("Connection: close\r\n"),
7344 MockRead("Content-Length: 42\r\n"),
[email protected]076c85082009-04-10 23:21:367345 MockRead("Content-Type: text/html\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297346 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297347 };
7348
7349 MockWrite data_writes2[] = {
bnc691fda62016-08-12 00:43:167350 // After restarting with a null identity, this is the
7351 // request we should be issuing -- the final header line contains a Type
7352 // 1 message.
7353 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557354 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167355 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377356 "Authorization: NTLM "),
7357 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297358
bnc691fda62016-08-12 00:43:167359 // After calling trans.RestartWithAuth(), we should send a Type 3 message
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377360 // (using incorrect credentials). The second request continues on the
7361 // same connection.
bnc691fda62016-08-12 00:43:167362 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557363 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167364 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377365 "Authorization: NTLM "),
7366 MockWrite(wrong_password_authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297367 };
7368
7369 MockRead data_reads2[] = {
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377370 // The origin server responds with a Type 2 message.
7371 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7372 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7373 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
7374 MockRead("Content-Type: text/html\r\n\r\n"),
7375 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297376
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377377 // Wrong password.
7378 MockRead("HTTP/1.1 401 Access Denied\r\n"),
7379 MockRead("WWW-Authenticate: NTLM\r\n"), MockRead("Connection: close\r\n"),
7380 MockRead("Content-Length: 42\r\n"),
7381 MockRead("Content-Type: text/html\r\n\r\n"),
7382 // Missing content -- won't matter, as connection will be reset.
[email protected]385a4672009-03-11 22:21:297383 };
7384
7385 MockWrite data_writes3[] = {
bnc691fda62016-08-12 00:43:167386 // After restarting with a null identity, this is the
7387 // request we should be issuing -- the final header line contains a Type
7388 // 1 message.
7389 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557390 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167391 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377392 "Authorization: NTLM "),
7393 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297394
bnc691fda62016-08-12 00:43:167395 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7396 // (the credentials for the origin server). The second request continues
7397 // on the same connection.
7398 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557399 "Host: server\r\n"
bnc691fda62016-08-12 00:43:167400 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377401 "Authorization: NTLM "),
7402 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
[email protected]385a4672009-03-11 22:21:297403 };
7404
7405 MockRead data_reads3[] = {
Bence Béky1e4ef192017-09-18 19:58:027406 // The origin server responds with a Type 2 message.
7407 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377408 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7409 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027410 MockRead("Content-Type: text/html\r\n\r\n"),
7411 MockRead("You are not authorized to view this page\r\n"),
[email protected]385a4672009-03-11 22:21:297412
Bence Béky1e4ef192017-09-18 19:58:027413 // Lastly we get the desired content.
7414 MockRead("HTTP/1.1 200 OK\r\n"),
7415 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
7416 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
[email protected]385a4672009-03-11 22:21:297417 };
7418
Ryan Sleevib8d7ea02018-05-07 20:01:017419 StaticSocketDataProvider data1(data_reads1, data_writes1);
7420 StaticSocketDataProvider data2(data_reads2, data_writes2);
7421 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:077422 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7423 session_deps_.socket_factory->AddSocketDataProvider(&data2);
7424 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]385a4672009-03-11 22:21:297425
Bence Béky83eb3512017-09-05 12:56:097426 SSLSocketDataProvider ssl1(ASYNC, OK);
7427 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7428 SSLSocketDataProvider ssl2(ASYNC, OK);
7429 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
7430 SSLSocketDataProvider ssl3(ASYNC, OK);
7431 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl3);
7432
[email protected]49639fa2011-12-20 23:22:417433 TestCompletionCallback callback1;
[email protected]385a4672009-03-11 22:21:297434
bnc691fda62016-08-12 00:43:167435 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:507436
tfarina42834112016-09-22 13:38:207437 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017438 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297439
7440 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017441 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297442
bnc691fda62016-08-12 00:43:167443 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]385a4672009-03-11 22:21:297444
bnc691fda62016-08-12 00:43:167445 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527446 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587447 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
[email protected]385a4672009-03-11 22:21:297448
[email protected]49639fa2011-12-20 23:22:417449 TestCompletionCallback callback2;
[email protected]385a4672009-03-11 22:21:297450
[email protected]0757e7702009-03-27 04:00:227451 // Enter the wrong password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377452 rv = trans.RestartWithAuth(
7453 AuthCredentials(ntlm::test::kDomainUserCombined, kWrongPassword),
7454 callback2.callback());
robpercival214763f2016-07-01 23:27:017455 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]385a4672009-03-11 22:21:297456
[email protected]10af5fe72011-01-31 16:17:257457 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:017458 EXPECT_THAT(rv, IsOk());
[email protected]385a4672009-03-11 22:21:297459
bnc691fda62016-08-12 00:43:167460 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:417461 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:167462 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
robpercival214763f2016-07-01 23:27:017463 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257464 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:017465 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:167466 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:227467
bnc691fda62016-08-12 00:43:167468 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527469 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587470 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
[email protected]0757e7702009-03-27 04:00:227471
[email protected]49639fa2011-12-20 23:22:417472 TestCompletionCallback callback4;
[email protected]0757e7702009-03-27 04:00:227473
7474 // Now enter the right password.
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377475 rv = trans.RestartWithAuth(
7476 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7477 callback4.callback());
robpercival214763f2016-07-01 23:27:017478 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]10af5fe72011-01-31 16:17:257479
7480 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:017481 EXPECT_THAT(rv, IsOk());
[email protected]10af5fe72011-01-31 16:17:257482
bnc691fda62016-08-12 00:43:167483 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]10af5fe72011-01-31 16:17:257484
[email protected]49639fa2011-12-20 23:22:417485 TestCompletionCallback callback5;
[email protected]10af5fe72011-01-31 16:17:257486
7487 // One more roundtrip
bnc691fda62016-08-12 00:43:167488 rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback());
robpercival214763f2016-07-01 23:27:017489 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:227490
7491 rv = callback5.WaitForResult();
robpercival214763f2016-07-01 23:27:017492 EXPECT_THAT(rv, IsOk());
[email protected]0757e7702009-03-27 04:00:227493
bnc691fda62016-08-12 00:43:167494 response = trans.GetResponseInfo();
Emily Starkf2c9bbd2019-04-09 17:08:587495 EXPECT_FALSE(response->auth_challenge.has_value());
Bence Béky1e4ef192017-09-18 19:58:027496 EXPECT_EQ(14, response->headers->GetContentLength());
7497
7498 std::string response_data;
7499 rv = ReadTransaction(&trans, &response_data);
7500 EXPECT_THAT(rv, IsOk());
7501 EXPECT_EQ("Please Login\r\n", response_data);
7502
7503 EXPECT_TRUE(data1.AllReadDataConsumed());
7504 EXPECT_TRUE(data1.AllWriteDataConsumed());
7505 EXPECT_TRUE(data2.AllReadDataConsumed());
7506 EXPECT_TRUE(data2.AllWriteDataConsumed());
7507 EXPECT_TRUE(data3.AllReadDataConsumed());
7508 EXPECT_TRUE(data3.AllWriteDataConsumed());
[email protected]385a4672009-03-11 22:21:297509}
Bence Béky83eb3512017-09-05 12:56:097510
Bence Béky3238f2e12017-09-22 22:44:497511// Server requests NTLM authentication, which is not supported over HTTP/2.
7512// Subsequent request with authorization header should be sent over HTTP/1.1.
Bence Béky83eb3512017-09-05 12:56:097513TEST_F(HttpNetworkTransactionTest, NTLMOverHttp2) {
Zentaro Kavanagh6ccee512017-09-28 18:34:097514 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7515 MockGetMSTime, MockGenerateRandom, MockGetHostName);
Bence Béky83eb3512017-09-05 12:56:097516
Zentaro Kavanagh1890a3d2018-01-29 19:52:557517 const char* kUrl = "https://server/kids/login.aspx";
Bence Béky83eb3512017-09-05 12:56:097518
7519 HttpRequestInfo request;
7520 request.method = "GET";
7521 request.url = GURL(kUrl);
Ramin Halavatib5e433e62018-02-07 07:41:107522 request.traffic_annotation =
7523 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky83eb3512017-09-05 12:56:097524
7525 // First request without credentials.
Ryan Hamilton0239aac2018-05-19 00:03:137526 spdy::SpdyHeaderBlock request_headers0(
7527 spdy_util_.ConstructGetHeaderBlock(kUrl));
7528 spdy::SpdySerializedFrame request0(spdy_util_.ConstructSpdyHeaders(
Bence Béky83eb3512017-09-05 12:56:097529 1, std::move(request_headers0), LOWEST, true));
7530
Ryan Hamilton0239aac2018-05-19 00:03:137531 spdy::SpdyHeaderBlock response_headers0;
7532 response_headers0[spdy::kHttp2StatusHeader] = "401";
Bence Béky83eb3512017-09-05 12:56:097533 response_headers0["www-authenticate"] = "NTLM";
Ryan Hamilton0239aac2018-05-19 00:03:137534 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyResponseHeaders(
Bence Béky83eb3512017-09-05 12:56:097535 1, std::move(response_headers0), true));
7536
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377537 // Stream 1 is closed.
7538 spdy_util_.UpdateWithStreamDestruction(1);
7539
7540 // Generate the NTLM messages based on known test data.
7541 std::string negotiate_msg;
7542 std::string challenge_msg;
7543 std::string authenticate_msg;
7544 base::Base64Encode(
7545 base::StringPiece(
7546 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247547 base::size(ntlm::test::kExpectedNegotiateMsg)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377548 &negotiate_msg);
Zentaro Kavanagh1890a3d2018-01-29 19:52:557549 base::Base64Encode(
7550 base::StringPiece(
7551 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247552 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
Zentaro Kavanagh1890a3d2018-01-29 19:52:557553 &challenge_msg);
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377554 base::Base64Encode(
7555 base::StringPiece(
Zentaro Kavanagh6ccee512017-09-28 18:34:097556 reinterpret_cast<const char*>(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557557 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247558 base::size(
Zentaro Kavanagh1890a3d2018-01-29 19:52:557559 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377560 &authenticate_msg);
7561
7562 // Retry with authorization header.
Ryan Hamilton0239aac2018-05-19 00:03:137563 spdy::SpdyHeaderBlock request_headers1(
7564 spdy_util_.ConstructGetHeaderBlock(kUrl));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377565 request_headers1["authorization"] = std::string("NTLM ") + negotiate_msg;
Ryan Hamilton0239aac2018-05-19 00:03:137566 spdy::SpdySerializedFrame request1(spdy_util_.ConstructSpdyHeaders(
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377567 3, std::move(request_headers1), LOWEST, true));
7568
Ryan Hamilton0239aac2018-05-19 00:03:137569 spdy::SpdySerializedFrame rst(
7570 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_HTTP_1_1_REQUIRED));
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377571
Bence Béky3238f2e12017-09-22 22:44:497572 MockWrite writes0[] = {CreateMockWrite(request0, 0)};
7573 MockRead reads0[] = {CreateMockRead(resp, 1), MockRead(ASYNC, 0, 2)};
Bence Béky83eb3512017-09-05 12:56:097574
7575 // Retry yet again using HTTP/1.1.
7576 MockWrite writes1[] = {
7577 // After restarting with a null identity, this is the
7578 // request we should be issuing -- the final header line contains a Type
7579 // 1 message.
7580 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557581 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097582 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377583 "Authorization: NTLM "),
7584 MockWrite(negotiate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097585
7586 // After calling trans.RestartWithAuth(), we should send a Type 3 message
7587 // (the credentials for the origin server). The second request continues
7588 // on the same connection.
7589 MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
Zentaro Kavanagh1890a3d2018-01-29 19:52:557590 "Host: server\r\n"
Bence Béky83eb3512017-09-05 12:56:097591 "Connection: keep-alive\r\n"
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377592 "Authorization: NTLM "),
7593 MockWrite(authenticate_msg.c_str()), MockWrite("\r\n\r\n"),
Bence Béky83eb3512017-09-05 12:56:097594 };
7595
7596 MockRead reads1[] = {
7597 // The origin server responds with a Type 2 message.
7598 MockRead("HTTP/1.1 401 Access Denied\r\n"),
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377599 MockRead("WWW-Authenticate: NTLM "), MockRead(challenge_msg.c_str()),
7600 MockRead("\r\n"), MockRead("Content-Length: 42\r\n"),
Bence Béky83eb3512017-09-05 12:56:097601 MockRead("Content-Type: text/html\r\n\r\n"),
7602 MockRead("You are not authorized to view this page\r\n"),
7603
7604 // Lastly we get the desired content.
7605 MockRead("HTTP/1.1 200 OK\r\n"),
7606 MockRead("Content-Type: text/html; charset=utf-8\r\n"),
Bence Béky1e4ef192017-09-18 19:58:027607 MockRead("Content-Length: 14\r\n\r\n"), MockRead("Please Login\r\n"),
Bence Béky83eb3512017-09-05 12:56:097608 };
Ryan Sleevib8d7ea02018-05-07 20:01:017609 SequencedSocketData data0(reads0, writes0);
7610 StaticSocketDataProvider data1(reads1, writes1);
Bence Béky83eb3512017-09-05 12:56:097611 session_deps_.socket_factory->AddSocketDataProvider(&data0);
7612 session_deps_.socket_factory->AddSocketDataProvider(&data1);
7613
7614 SSLSocketDataProvider ssl0(ASYNC, OK);
7615 ssl0.next_proto = kProtoHTTP2;
7616 SSLSocketDataProvider ssl1(ASYNC, OK);
7617 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl0);
7618 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
7619
7620 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7621 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7622
7623 TestCompletionCallback callback1;
7624 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
7625 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7626
7627 rv = callback1.WaitForResult();
7628 EXPECT_THAT(rv, IsOk());
7629
7630 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7631
7632 const HttpResponseInfo* response = trans.GetResponseInfo();
7633 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587634 EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge));
Bence Béky83eb3512017-09-05 12:56:097635
7636 TestCompletionCallback callback2;
7637
Zentaro Kavanagh5b27a6e22017-09-25 23:00:377638 rv = trans.RestartWithAuth(
7639 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7640 callback2.callback());
Bence Béky83eb3512017-09-05 12:56:097641 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7642
7643 rv = callback2.WaitForResult();
7644 EXPECT_THAT(rv, IsOk());
7645
7646 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7647
7648 response = trans.GetResponseInfo();
7649 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587650 EXPECT_FALSE(response->auth_challenge.has_value());
Bence Béky83eb3512017-09-05 12:56:097651
7652 TestCompletionCallback callback3;
7653
7654 rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback());
7655 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7656
7657 rv = callback3.WaitForResult();
7658 EXPECT_THAT(rv, IsOk());
7659
7660 response = trans.GetResponseInfo();
7661 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587662 EXPECT_FALSE(response->auth_challenge.has_value());
Bence Béky1e4ef192017-09-18 19:58:027663 EXPECT_EQ(14, response->headers->GetContentLength());
7664
7665 std::string response_data;
7666 rv = ReadTransaction(&trans, &response_data);
7667 EXPECT_THAT(rv, IsOk());
7668 EXPECT_EQ("Please Login\r\n", response_data);
7669
7670 EXPECT_TRUE(data0.AllReadDataConsumed());
7671 EXPECT_TRUE(data0.AllWriteDataConsumed());
7672 EXPECT_TRUE(data1.AllReadDataConsumed());
7673 EXPECT_TRUE(data1.AllWriteDataConsumed());
Bence Béky83eb3512017-09-05 12:56:097674}
David Benjamin5cb91132018-04-06 05:54:497675
7676// Test that, if we have an NTLM proxy and the origin resets the connection, we
7677// do no retry forever checking for TLS version interference. This is a
David Benjamind61bd532019-04-23 21:11:377678// regression test for https://crbug.com/823387. The version interference probe
7679// has since been removed, but retain the regression test so we can update it if
7680// we add future TLS retries.
David Benjamin5cb91132018-04-06 05:54:497681TEST_F(HttpNetworkTransactionTest, NTLMProxyTLSHandshakeReset) {
7682 // The NTLM test data expects the proxy to be named 'server'. The origin is
7683 // https://origin/.
7684 session_deps_.proxy_resolution_service =
7685 ProxyResolutionService::CreateFixedFromPacResult(
7686 "PROXY server", TRAFFIC_ANNOTATION_FOR_TESTS);
7687
7688 SSLConfig config;
David Benjamin5cb91132018-04-06 05:54:497689 session_deps_.ssl_config_service =
Ryan Sleevib8449e02018-07-15 04:31:077690 std::make_unique<TestSSLConfigService>(config);
David Benjamin5cb91132018-04-06 05:54:497691
7692 HttpRequestInfo request;
7693 request.method = "GET";
7694 request.url = GURL("https://origin/");
7695 request.traffic_annotation =
7696 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7697
7698 // Ensure load is not disrupted by flags which suppress behaviour specific
7699 // to other auth schemes.
7700 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
7701
7702 HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(
7703 MockGetMSTime, MockGenerateRandom, MockGetHostName);
7704 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
7705
7706 // Generate the NTLM messages based on known test data.
7707 std::string negotiate_msg;
7708 std::string challenge_msg;
7709 std::string authenticate_msg;
7710 base::Base64Encode(
7711 base::StringPiece(
7712 reinterpret_cast<const char*>(ntlm::test::kExpectedNegotiateMsg),
Avi Drissman4365a4782018-12-28 19:26:247713 base::size(ntlm::test::kExpectedNegotiateMsg)),
David Benjamin5cb91132018-04-06 05:54:497714 &negotiate_msg);
7715 base::Base64Encode(
7716 base::StringPiece(
7717 reinterpret_cast<const char*>(ntlm::test::kChallengeMsgFromSpecV2),
Avi Drissman4365a4782018-12-28 19:26:247718 base::size(ntlm::test::kChallengeMsgFromSpecV2)),
David Benjamin5cb91132018-04-06 05:54:497719 &challenge_msg);
7720 base::Base64Encode(
7721 base::StringPiece(
7722 reinterpret_cast<const char*>(
7723 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2),
Avi Drissman4365a4782018-12-28 19:26:247724 base::size(
David Benjamin5cb91132018-04-06 05:54:497725 ntlm::test::kExpectedAuthenticateMsgEmptyChannelBindingsV2)),
7726 &authenticate_msg);
7727
7728 MockWrite data_writes[] = {
7729 // The initial CONNECT request.
7730 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7731 "Host: origin:443\r\n"
7732 "Proxy-Connection: keep-alive\r\n\r\n"),
7733
7734 // After restarting with an identity.
7735 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7736 "Host: origin:443\r\n"
7737 "Proxy-Connection: keep-alive\r\n"
7738 "Proxy-Authorization: NTLM "),
7739 MockWrite(negotiate_msg.c_str()),
7740 // End headers.
7741 MockWrite("\r\n\r\n"),
7742
7743 // The second restart.
7744 MockWrite("CONNECT origin:443 HTTP/1.1\r\n"
7745 "Host: origin:443\r\n"
7746 "Proxy-Connection: keep-alive\r\n"
7747 "Proxy-Authorization: NTLM "),
7748 MockWrite(authenticate_msg.c_str()),
7749 // End headers.
7750 MockWrite("\r\n\r\n"),
7751 };
7752
7753 MockRead data_reads[] = {
7754 // The initial NTLM response.
7755 MockRead("HTTP/1.1 407 Access Denied\r\n"
7756 "Content-Length: 0\r\n"
7757 "Proxy-Authenticate: NTLM\r\n\r\n"),
7758
7759 // The NTLM challenge message.
7760 MockRead("HTTP/1.1 407 Access Denied\r\n"
7761 "Content-Length: 0\r\n"
7762 "Proxy-Authenticate: NTLM "),
7763 MockRead(challenge_msg.c_str()),
7764 // End headers.
7765 MockRead("\r\n\r\n"),
7766
7767 // Finally the tunnel is established.
7768 MockRead("HTTP/1.1 200 Connected\r\n\r\n"),
7769 };
7770
Ryan Sleevib8d7ea02018-05-07 20:01:017771 StaticSocketDataProvider data(data_reads, data_writes);
David Benjamin5cb91132018-04-06 05:54:497772 SSLSocketDataProvider data_ssl(ASYNC, ERR_CONNECTION_RESET);
David Benjamin5cb91132018-04-06 05:54:497773 session_deps_.socket_factory->AddSocketDataProvider(&data);
7774 session_deps_.socket_factory->AddSSLSocketDataProvider(&data_ssl);
David Benjamin5cb91132018-04-06 05:54:497775
7776 // Start the transaction. The proxy responds with an NTLM authentication
7777 // request.
7778 TestCompletionCallback callback;
7779 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
7780 int rv = callback.GetResult(
7781 trans.Start(&request, callback.callback(), NetLogWithSource()));
7782
7783 EXPECT_THAT(rv, IsOk());
7784 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
7785 const HttpResponseInfo* response = trans.GetResponseInfo();
7786 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587787 EXPECT_TRUE(CheckNTLMProxyAuth(response->auth_challenge));
David Benjamin5cb91132018-04-06 05:54:497788
David Benjamind61bd532019-04-23 21:11:377789 // Configure credentials and restart. The proxy responds with the challenge
7790 // message.
David Benjamin5cb91132018-04-06 05:54:497791 rv = callback.GetResult(trans.RestartWithAuth(
7792 AuthCredentials(ntlm::test::kDomainUserCombined, ntlm::test::kPassword),
7793 callback.callback()));
7794 EXPECT_THAT(rv, IsOk());
7795 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
7796 response = trans.GetResponseInfo();
7797 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:587798 EXPECT_FALSE(response->auth_challenge.has_value());
David Benjamin5cb91132018-04-06 05:54:497799
David Benjamind61bd532019-04-23 21:11:377800 // Restart once more. The tunnel will be established and then the SSL
7801 // handshake will reset.
David Benjamin5cb91132018-04-06 05:54:497802 rv = callback.GetResult(
7803 trans.RestartWithAuth(AuthCredentials(), callback.callback()));
7804 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
7805}
7806
[email protected]ea9dc9a2009-09-05 00:43:327807#endif // NTLM_PORTABLE
[email protected]385a4672009-03-11 22:21:297808
[email protected]4ddaf2502008-10-23 18:26:197809// Test reading a server response which has only headers, and no body.
7810// After some maximum number of bytes is consumed, the transaction should
7811// fail with ERR_RESPONSE_HEADERS_TOO_BIG.
bncd16676a2016-07-20 16:23:017812TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
[email protected]1c773ea12009-04-28 19:58:427813 HttpRequestInfo request;
[email protected]4ddaf2502008-10-23 18:26:197814 request.method = "GET";
bncce36dca22015-04-21 22:11:237815 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107816 request.traffic_annotation =
7817 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]4ddaf2502008-10-23 18:26:197818
danakj1fd259a02016-04-16 03:17:097819 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167820 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277821
[email protected]b75b7b2f2009-10-06 00:54:537822 // Respond with 300 kb of headers (we should fail after 256 kb).
[email protected]15a5ccf82008-10-23 19:57:437823 std::string large_headers_string;
[email protected]b75b7b2f2009-10-06 00:54:537824 FillLargeHeadersString(&large_headers_string, 300 * 1024);
[email protected]4ddaf2502008-10-23 18:26:197825
7826 MockRead data_reads[] = {
7827 MockRead("HTTP/1.0 200 OK\r\n"),
[email protected]8ddf8322012-02-23 18:08:067828 MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
[email protected]4ddaf2502008-10-23 18:26:197829 MockRead("\r\nBODY"),
[email protected]8ddf8322012-02-23 18:08:067830 MockRead(SYNCHRONOUS, OK),
[email protected]4ddaf2502008-10-23 18:26:197831 };
Ryan Sleevib8d7ea02018-05-07 20:01:017832 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077833 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]4ddaf2502008-10-23 18:26:197834
[email protected]49639fa2011-12-20 23:22:417835 TestCompletionCallback callback;
[email protected]4ddaf2502008-10-23 18:26:197836
tfarina42834112016-09-22 13:38:207837 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017838 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]4ddaf2502008-10-23 18:26:197839
7840 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017841 EXPECT_THAT(rv, IsError(ERR_RESPONSE_HEADERS_TOO_BIG));
[email protected]4ddaf2502008-10-23 18:26:197842}
[email protected]f4e426b2008-11-05 00:24:497843
7844// Make sure that we don't try to reuse a TCPClientSocket when failing to
7845// establish tunnel.
7846// http://code.google.com/p/chromium/issues/detail?id=3772
bncd16676a2016-07-20 16:23:017847TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
[email protected]cb9bf6ca2011-01-28 13:15:277848 HttpRequestInfo request;
7849 request.method = "GET";
bncce36dca22015-04-21 22:11:237850 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107851 request.traffic_annotation =
7852 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:277853
[email protected]f4e426b2008-11-05 00:24:497854 // Configure against proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:497855 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
7856 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]db8f44c2008-12-13 04:52:017857
danakj1fd259a02016-04-16 03:17:097858 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f4e426b2008-11-05 00:24:497859
bnc87dcefc2017-05-25 12:47:587860 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:197861 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]f4e426b2008-11-05 00:24:497862
[email protected]f4e426b2008-11-05 00:24:497863 // Since we have proxy, should try to establish tunnel.
7864 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:177865 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
7866 "Host: www.example.org:443\r\n"
7867 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]f4e426b2008-11-05 00:24:497868 };
7869
[email protected]77848d12008-11-14 00:00:227870 // The proxy responds to the connect with a 404, using a persistent
[email protected]f4e426b2008-11-05 00:24:497871 // connection. Usually a proxy would return 501 (not implemented),
7872 // or 200 (tunnel established).
7873 MockRead data_reads1[] = {
mmenked39192ee2015-12-09 00:57:237874 MockRead("HTTP/1.1 404 Not Found\r\n"),
7875 MockRead("Content-Length: 10\r\n\r\n"),
7876 MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
[email protected]f4e426b2008-11-05 00:24:497877 };
7878
Ryan Sleevib8d7ea02018-05-07 20:01:017879 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:077880 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f4e426b2008-11-05 00:24:497881
[email protected]49639fa2011-12-20 23:22:417882 TestCompletionCallback callback1;
[email protected]f4e426b2008-11-05 00:24:497883
tfarina42834112016-09-22 13:38:207884 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017885 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f4e426b2008-11-05 00:24:497886
7887 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:017888 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]f4e426b2008-11-05 00:24:497889
[email protected]b4404c02009-04-10 16:38:527890 // Empty the current queue. This is necessary because idle sockets are
7891 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557892 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:527893
[email protected]f4e426b2008-11-05 00:24:497894 // We now check to make sure the TCPClientSocket was not added back to
7895 // the pool.
[email protected]90499482013-06-01 00:39:507896 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497897 trans.reset();
fdoray92e35a72016-06-10 15:54:557898 base::RunLoop().RunUntilIdle();
[email protected]f4e426b2008-11-05 00:24:497899 // Make sure that the socket didn't get recycled after calling the destructor.
[email protected]90499482013-06-01 00:39:507900 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]f4e426b2008-11-05 00:24:497901}
[email protected]372d34a2008-11-05 21:30:517902
[email protected]1b157c02009-04-21 01:55:407903// Make sure that we recycle a socket after reading all of the response body.
bncd16676a2016-07-20 16:23:017904TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
[email protected]1c773ea12009-04-28 19:58:427905 HttpRequestInfo request;
[email protected]1b157c02009-04-21 01:55:407906 request.method = "GET";
bncce36dca22015-04-21 22:11:237907 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107908 request.traffic_annotation =
7909 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1b157c02009-04-21 01:55:407910
danakj1fd259a02016-04-16 03:17:097911 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:277912
bnc691fda62016-08-12 00:43:167913 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:277914
[email protected]1b157c02009-04-21 01:55:407915 MockRead data_reads[] = {
7916 // A part of the response body is received with the response headers.
7917 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
7918 // The rest of the response body is received in two parts.
7919 MockRead("lo"),
7920 MockRead(" world"),
7921 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:067922 MockRead(SYNCHRONOUS, OK),
[email protected]1b157c02009-04-21 01:55:407923 };
7924
Ryan Sleevib8d7ea02018-05-07 20:01:017925 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:077926 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1b157c02009-04-21 01:55:407927
[email protected]49639fa2011-12-20 23:22:417928 TestCompletionCallback callback;
[email protected]1b157c02009-04-21 01:55:407929
tfarina42834112016-09-22 13:38:207930 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:017931 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1b157c02009-04-21 01:55:407932
7933 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:017934 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407935
bnc691fda62016-08-12 00:43:167936 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527937 ASSERT_TRUE(response);
[email protected]1b157c02009-04-21 01:55:407938
wezca1070932016-05-26 20:30:527939 EXPECT_TRUE(response->headers);
[email protected]1b157c02009-04-21 01:55:407940 std::string status_line = response->headers->GetStatusLine();
7941 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
7942
[email protected]90499482013-06-01 00:39:507943 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407944
7945 std::string response_data;
bnc691fda62016-08-12 00:43:167946 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:017947 EXPECT_THAT(rv, IsOk());
[email protected]1b157c02009-04-21 01:55:407948 EXPECT_EQ("hello world", response_data);
7949
7950 // Empty the current queue. This is necessary because idle sockets are
7951 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:557952 base::RunLoop().RunUntilIdle();
[email protected]1b157c02009-04-21 01:55:407953
7954 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:507955 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]1b157c02009-04-21 01:55:407956}
7957
[email protected]76a505b2010-08-25 06:23:007958// Make sure that we recycle a SSL socket after reading all of the response
7959// body.
bncd16676a2016-07-20 16:23:017960TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
[email protected]76a505b2010-08-25 06:23:007961 HttpRequestInfo request;
7962 request.method = "GET";
bncce36dca22015-04-21 22:11:237963 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:107964 request.traffic_annotation =
7965 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:007966
7967 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:237968 MockWrite(
7969 "GET / HTTP/1.1\r\n"
7970 "Host: www.example.org\r\n"
7971 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:007972 };
7973
7974 MockRead data_reads[] = {
7975 MockRead("HTTP/1.1 200 OK\r\n"),
7976 MockRead("Content-Length: 11\r\n\r\n"),
7977 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:067978 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:007979 };
7980
[email protected]8ddf8322012-02-23 18:08:067981 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:077982 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:007983
Ryan Sleevib8d7ea02018-05-07 20:01:017984 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:077985 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]76a505b2010-08-25 06:23:007986
[email protected]49639fa2011-12-20 23:22:417987 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:007988
danakj1fd259a02016-04-16 03:17:097989 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:167990 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:007991
tfarina42834112016-09-22 13:38:207992 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:007993
robpercival214763f2016-07-01 23:27:017994 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
7995 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:007996
bnc691fda62016-08-12 00:43:167997 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:527998 ASSERT_TRUE(response);
7999 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008000 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8001
[email protected]90499482013-06-01 00:39:508002 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008003
8004 std::string response_data;
bnc691fda62016-08-12 00:43:168005 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018006 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008007 EXPECT_EQ("hello world", response_data);
8008
8009 // Empty the current queue. This is necessary because idle sockets are
8010 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558011 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008012
8013 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238014 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008015}
8016
8017// Grab a SSL socket, use it, and put it back into the pool. Then, reuse it
8018// from the pool and make sure that we recover okay.
bncd16676a2016-07-20 16:23:018019TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
[email protected]76a505b2010-08-25 06:23:008020 HttpRequestInfo request;
8021 request.method = "GET";
bncce36dca22015-04-21 22:11:238022 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:108023 request.traffic_annotation =
8024 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:008025
8026 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:238027 MockWrite(
8028 "GET / HTTP/1.1\r\n"
8029 "Host: www.example.org\r\n"
8030 "Connection: keep-alive\r\n\r\n"),
8031 MockWrite(
8032 "GET / HTTP/1.1\r\n"
8033 "Host: www.example.org\r\n"
8034 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:008035 };
8036
8037 MockRead data_reads[] = {
mmenke911ee0222015-12-04 03:58:428038 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8039 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
[email protected]76a505b2010-08-25 06:23:008040
[email protected]8ddf8322012-02-23 18:08:068041 SSLSocketDataProvider ssl(ASYNC, OK);
8042 SSLSocketDataProvider ssl2(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:078043 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8044 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
[email protected]76a505b2010-08-25 06:23:008045
Ryan Sleevib8d7ea02018-05-07 20:01:018046 StaticSocketDataProvider data(data_reads, data_writes);
8047 StaticSocketDataProvider data2(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:078048 session_deps_.socket_factory->AddSocketDataProvider(&data);
8049 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]76a505b2010-08-25 06:23:008050
[email protected]49639fa2011-12-20 23:22:418051 TestCompletionCallback callback;
[email protected]76a505b2010-08-25 06:23:008052
danakj1fd259a02016-04-16 03:17:098053 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:588054 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:198055 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008056
tfarina42834112016-09-22 13:38:208057 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008058
robpercival214763f2016-07-01 23:27:018059 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8060 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008061
8062 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528063 ASSERT_TRUE(response);
8064 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008065 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8066
[email protected]90499482013-06-01 00:39:508067 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008068
8069 std::string response_data;
8070 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018071 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008072 EXPECT_EQ("hello world", response_data);
8073
8074 // Empty the current queue. This is necessary because idle sockets are
8075 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558076 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008077
8078 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238079 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008080
8081 // Now start the second transaction, which should reuse the previous socket.
8082
bnc87dcefc2017-05-25 12:47:588083 trans =
Jeremy Roman0579ed62017-08-29 15:56:198084 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]76a505b2010-08-25 06:23:008085
tfarina42834112016-09-22 13:38:208086 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
[email protected]76a505b2010-08-25 06:23:008087
robpercival214763f2016-07-01 23:27:018088 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8089 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]76a505b2010-08-25 06:23:008090
8091 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:528092 ASSERT_TRUE(response);
8093 ASSERT_TRUE(response->headers);
[email protected]76a505b2010-08-25 06:23:008094 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8095
[email protected]90499482013-06-01 00:39:508096 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008097
8098 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:018099 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:008100 EXPECT_EQ("hello world", response_data);
8101
8102 // Empty the current queue. This is necessary because idle sockets are
8103 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558104 base::RunLoop().RunUntilIdle();
[email protected]76a505b2010-08-25 06:23:008105
8106 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238107 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]76a505b2010-08-25 06:23:008108}
8109
maksim.sisov0adf8592016-07-15 06:25:568110// Grab a socket, use it, and put it back into the pool. Then, make
8111// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018112TEST_F(HttpNetworkTransactionTest, FlushSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568113 HttpRequestInfo request;
8114 request.method = "GET";
8115 request.url = GURL("http://www.example.org/");
8116 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:108117 request.traffic_annotation =
8118 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568119
8120 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8121
bnc691fda62016-08-12 00:43:168122 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568123
8124 MockRead data_reads[] = {
8125 // A part of the response body is received with the response headers.
8126 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8127 // The rest of the response body is received in two parts.
8128 MockRead("lo"), MockRead(" world"),
8129 MockRead("junk"), // Should not be read!!
8130 MockRead(SYNCHRONOUS, OK),
8131 };
8132
Ryan Sleevib8d7ea02018-05-07 20:01:018133 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
maksim.sisov0adf8592016-07-15 06:25:568134 session_deps_.socket_factory->AddSocketDataProvider(&data);
8135
8136 TestCompletionCallback callback;
8137
tfarina42834112016-09-22 13:38:208138 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568139 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8140
8141 EXPECT_THAT(callback.GetResult(rv), IsOk());
8142
bnc691fda62016-08-12 00:43:168143 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568144 ASSERT_TRUE(response);
8145 EXPECT_TRUE(response->headers);
8146 std::string status_line = response->headers->GetStatusLine();
8147 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8148
8149 // Make memory critical notification and ensure the transaction still has been
8150 // operating right.
8151 base::MemoryPressureListener::NotifyMemoryPressure(
8152 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8153 base::RunLoop().RunUntilIdle();
8154
8155 // Socket should not be flushed as long as it is not idle.
8156 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8157
8158 std::string response_data;
bnc691fda62016-08-12 00:43:168159 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568160 EXPECT_THAT(rv, IsOk());
8161 EXPECT_EQ("hello world", response_data);
8162
8163 // Empty the current queue. This is necessary because idle sockets are
8164 // added to the connection pool asynchronously with a PostTask.
8165 base::RunLoop().RunUntilIdle();
8166
8167 // We now check to make sure the socket was added back to the pool.
8168 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8169
8170 // Idle sockets should be flushed now.
8171 base::MemoryPressureListener::NotifyMemoryPressure(
8172 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8173 base::RunLoop().RunUntilIdle();
8174
8175 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8176}
8177
yucliu48f235d2018-01-11 00:59:558178// Disable idle socket closing on memory pressure.
8179// Grab a socket, use it, and put it back into the pool. Then, make
8180// low memory notification and ensure the socket pool is NOT flushed.
8181TEST_F(HttpNetworkTransactionTest, NoFlushSocketPoolOnLowMemoryNotifications) {
8182 HttpRequestInfo request;
8183 request.method = "GET";
8184 request.url = GURL("http://www.example.org/");
8185 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:108186 request.traffic_annotation =
8187 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
yucliu48f235d2018-01-11 00:59:558188
8189 // Disable idle socket closing on memory pressure.
8190 session_deps_.disable_idle_sockets_close_on_memory_pressure = true;
8191 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
8192
8193 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
8194
8195 MockRead data_reads[] = {
8196 // A part of the response body is received with the response headers.
8197 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
8198 // The rest of the response body is received in two parts.
8199 MockRead("lo"), MockRead(" world"),
8200 MockRead("junk"), // Should not be read!!
8201 MockRead(SYNCHRONOUS, OK),
8202 };
8203
Ryan Sleevib8d7ea02018-05-07 20:01:018204 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
yucliu48f235d2018-01-11 00:59:558205 session_deps_.socket_factory->AddSocketDataProvider(&data);
8206
8207 TestCompletionCallback callback;
8208
8209 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
8210 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
8211
8212 EXPECT_THAT(callback.GetResult(rv), IsOk());
8213
8214 const HttpResponseInfo* response = trans.GetResponseInfo();
8215 ASSERT_TRUE(response);
8216 EXPECT_TRUE(response->headers);
8217 std::string status_line = response->headers->GetStatusLine();
8218 EXPECT_EQ("HTTP/1.1 200 OK", status_line);
8219
8220 // Make memory critical notification and ensure the transaction still has been
8221 // operating right.
8222 base::MemoryPressureListener::NotifyMemoryPressure(
8223 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8224 base::RunLoop().RunUntilIdle();
8225
8226 // Socket should not be flushed as long as it is not idle.
8227 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
8228
8229 std::string response_data;
8230 rv = ReadTransaction(&trans, &response_data);
8231 EXPECT_THAT(rv, IsOk());
8232 EXPECT_EQ("hello world", response_data);
8233
8234 // Empty the current queue. This is necessary because idle sockets are
8235 // added to the connection pool asynchronously with a PostTask.
8236 base::RunLoop().RunUntilIdle();
8237
8238 // We now check to make sure the socket was added back to the pool.
8239 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8240
8241 // Idle sockets should NOT be flushed on moderate memory pressure.
8242 base::MemoryPressureListener::NotifyMemoryPressure(
8243 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE);
8244 base::RunLoop().RunUntilIdle();
8245
8246 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8247
8248 // Idle sockets should NOT be flushed on critical memory pressure.
8249 base::MemoryPressureListener::NotifyMemoryPressure(
8250 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8251 base::RunLoop().RunUntilIdle();
8252
8253 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
8254}
8255
maksim.sisov0adf8592016-07-15 06:25:568256// Grab an SSL socket, use it, and put it back into the pool. Then, make
8257// low memory notification and ensure the socket pool is flushed.
bncd16676a2016-07-20 16:23:018258TEST_F(HttpNetworkTransactionTest, FlushSSLSocketPoolOnLowMemoryNotifications) {
maksim.sisov0adf8592016-07-15 06:25:568259 HttpRequestInfo request;
8260 request.method = "GET";
8261 request.url = GURL("https://www.example.org/");
8262 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:108263 request.traffic_annotation =
8264 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
maksim.sisov0adf8592016-07-15 06:25:568265
8266 MockWrite data_writes[] = {
8267 MockWrite("GET / HTTP/1.1\r\n"
8268 "Host: www.example.org\r\n"
8269 "Connection: keep-alive\r\n\r\n"),
8270 };
8271
8272 MockRead data_reads[] = {
8273 MockRead("HTTP/1.1 200 OK\r\n"), MockRead("Content-Length: 11\r\n\r\n"),
8274 MockRead("hello world"), MockRead(ASYNC, ERR_CONNECTION_CLOSED)};
8275
8276 SSLSocketDataProvider ssl(ASYNC, OK);
8277 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
8278
Ryan Sleevib8d7ea02018-05-07 20:01:018279 StaticSocketDataProvider data(data_reads, data_writes);
maksim.sisov0adf8592016-07-15 06:25:568280 session_deps_.socket_factory->AddSocketDataProvider(&data);
8281
8282 TestCompletionCallback callback;
8283
8284 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168285 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
maksim.sisov0adf8592016-07-15 06:25:568286
Matt Menke9d5e2c92019-02-05 01:42:238287 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
tfarina42834112016-09-22 13:38:208288 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
maksim.sisov0adf8592016-07-15 06:25:568289
8290 EXPECT_THAT(callback.GetResult(rv), IsOk());
8291
bnc691fda62016-08-12 00:43:168292 const HttpResponseInfo* response = trans.GetResponseInfo();
maksim.sisov0adf8592016-07-15 06:25:568293 ASSERT_TRUE(response);
8294 ASSERT_TRUE(response->headers);
8295 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8296
8297 // Make memory critical notification and ensure the transaction still has been
8298 // operating right.
8299 base::MemoryPressureListener::NotifyMemoryPressure(
8300 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8301 base::RunLoop().RunUntilIdle();
8302
Matt Menke9d5e2c92019-02-05 01:42:238303 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568304
8305 std::string response_data;
bnc691fda62016-08-12 00:43:168306 rv = ReadTransaction(&trans, &response_data);
maksim.sisov0adf8592016-07-15 06:25:568307 EXPECT_THAT(rv, IsOk());
8308 EXPECT_EQ("hello world", response_data);
8309
8310 // Empty the current queue. This is necessary because idle sockets are
8311 // added to the connection pool asynchronously with a PostTask.
8312 base::RunLoop().RunUntilIdle();
8313
8314 // We now check to make sure the socket was added back to the pool.
Matt Menke9d5e2c92019-02-05 01:42:238315 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568316
8317 // Make memory notification once again and ensure idle socket is closed.
8318 base::MemoryPressureListener::NotifyMemoryPressure(
8319 base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL);
8320 base::RunLoop().RunUntilIdle();
8321
Matt Menke9d5e2c92019-02-05 01:42:238322 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
maksim.sisov0adf8592016-07-15 06:25:568323}
8324
[email protected]b4404c02009-04-10 16:38:528325// Make sure that we recycle a socket after a zero-length response.
8326// http://crbug.com/9880
bncd16676a2016-07-20 16:23:018327TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
[email protected]1c773ea12009-04-28 19:58:428328 HttpRequestInfo request;
[email protected]b4404c02009-04-10 16:38:528329 request.method = "GET";
bncce36dca22015-04-21 22:11:238330 request.url = GURL(
8331 "http://www.example.org/csi?v=3&s=web&action=&"
8332 "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
8333 "e=17259,18167,19592,19773,19981,20133,20173,20233&"
8334 "rt=prt.2642,ol.2649,xjs.2951");
Ramin Halavatib5e433e62018-02-07 07:41:108335 request.traffic_annotation =
8336 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b4404c02009-04-10 16:38:528337
danakj1fd259a02016-04-16 03:17:098338 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]cb9bf6ca2011-01-28 13:15:278339
[email protected]b4404c02009-04-10 16:38:528340 MockRead data_reads[] = {
8341 MockRead("HTTP/1.1 204 No Content\r\n"
8342 "Content-Length: 0\r\n"
8343 "Content-Type: text/html\r\n\r\n"),
8344 MockRead("junk"), // Should not be read!!
[email protected]8ddf8322012-02-23 18:08:068345 MockRead(SYNCHRONOUS, OK),
[email protected]b4404c02009-04-10 16:38:528346 };
8347
Ryan Sleevib8d7ea02018-05-07 20:01:018348 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:078349 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]b4404c02009-04-10 16:38:528350
mmenkecc2298e2015-12-07 18:20:188351 // Transaction must be created after the MockReads, so it's destroyed before
8352 // them.
bnc691fda62016-08-12 00:43:168353 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
mmenkecc2298e2015-12-07 18:20:188354
[email protected]49639fa2011-12-20 23:22:418355 TestCompletionCallback callback;
[email protected]b4404c02009-04-10 16:38:528356
tfarina42834112016-09-22 13:38:208357 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018358 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]b4404c02009-04-10 16:38:528359
8360 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018361 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528362
bnc691fda62016-08-12 00:43:168363 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528364 ASSERT_TRUE(response);
[email protected]b4404c02009-04-10 16:38:528365
wezca1070932016-05-26 20:30:528366 EXPECT_TRUE(response->headers);
[email protected]b4404c02009-04-10 16:38:528367 std::string status_line = response->headers->GetStatusLine();
8368 EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
8369
[email protected]90499482013-06-01 00:39:508370 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528371
8372 std::string response_data;
bnc691fda62016-08-12 00:43:168373 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018374 EXPECT_THAT(rv, IsOk());
[email protected]b4404c02009-04-10 16:38:528375 EXPECT_EQ("", response_data);
8376
8377 // Empty the current queue. This is necessary because idle sockets are
8378 // added to the connection pool asynchronously with a PostTask.
fdoray92e35a72016-06-10 15:54:558379 base::RunLoop().RunUntilIdle();
[email protected]b4404c02009-04-10 16:38:528380
8381 // We now check to make sure the socket was added back to the pool.
[email protected]90499482013-06-01 00:39:508382 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]b4404c02009-04-10 16:38:528383}
8384
bncd16676a2016-07-20 16:23:018385TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
danakj1fd259a02016-04-16 03:17:098386 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:228387 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:198388 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:228389 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:278390
[email protected]1c773ea12009-04-28 19:58:428391 HttpRequestInfo request[2];
[email protected]372d34a2008-11-05 21:30:518392 // Transaction 1: a GET request that succeeds. The socket is recycled
8393 // after use.
8394 request[0].method = "GET";
8395 request[0].url = GURL("http://www.google.com/");
8396 request[0].load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:108397 request[0].traffic_annotation =
8398 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518399 // Transaction 2: a POST request. Reuses the socket kept alive from
8400 // transaction 1. The first attempts fails when writing the POST data.
8401 // This causes the transaction to retry with a new socket. The second
8402 // attempt succeeds.
8403 request[1].method = "POST";
8404 request[1].url = GURL("http://www.google.com/login.cgi");
[email protected]329b68b2012-11-14 17:54:278405 request[1].upload_data_stream = &upload_data_stream;
[email protected]372d34a2008-11-05 21:30:518406 request[1].load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:108407 request[1].traffic_annotation =
8408 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]372d34a2008-11-05 21:30:518409
danakj1fd259a02016-04-16 03:17:098410 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]372d34a2008-11-05 21:30:518411
8412 // The first socket is used for transaction 1 and the first attempt of
8413 // transaction 2.
8414
8415 // The response of transaction 1.
8416 MockRead data_reads1[] = {
8417 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
8418 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:068419 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518420 };
8421 // The mock write results of transaction 1 and the first attempt of
8422 // transaction 2.
8423 MockWrite data_writes1[] = {
[email protected]8ddf8322012-02-23 18:08:068424 MockWrite(SYNCHRONOUS, 64), // GET
8425 MockWrite(SYNCHRONOUS, 93), // POST
8426 MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED), // POST data
[email protected]372d34a2008-11-05 21:30:518427 };
Ryan Sleevib8d7ea02018-05-07 20:01:018428 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]372d34a2008-11-05 21:30:518429
8430 // The second socket is used for the second attempt of transaction 2.
8431
8432 // The response of transaction 2.
8433 MockRead data_reads2[] = {
8434 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
8435 MockRead("welcome"),
[email protected]8ddf8322012-02-23 18:08:068436 MockRead(SYNCHRONOUS, OK),
[email protected]372d34a2008-11-05 21:30:518437 };
8438 // The mock write results of the second attempt of transaction 2.
8439 MockWrite data_writes2[] = {
[email protected]8ddf8322012-02-23 18:08:068440 MockWrite(SYNCHRONOUS, 93), // POST
8441 MockWrite(SYNCHRONOUS, 3), // POST data
[email protected]372d34a2008-11-05 21:30:518442 };
Ryan Sleevib8d7ea02018-05-07 20:01:018443 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]372d34a2008-11-05 21:30:518444
[email protected]bb88e1d32013-05-03 23:11:078445 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8446 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]372d34a2008-11-05 21:30:518447
thestig9d3bb0c2015-01-24 00:49:518448 const char* const kExpectedResponseData[] = {
[email protected]372d34a2008-11-05 21:30:518449 "hello world", "welcome"
8450 };
8451
8452 for (int i = 0; i < 2; ++i) {
bnc691fda62016-08-12 00:43:168453 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]372d34a2008-11-05 21:30:518454
[email protected]49639fa2011-12-20 23:22:418455 TestCompletionCallback callback;
[email protected]372d34a2008-11-05 21:30:518456
tfarina42834112016-09-22 13:38:208457 int rv = trans.Start(&request[i], callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018458 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]372d34a2008-11-05 21:30:518459
8460 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:018461 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518462
bnc691fda62016-08-12 00:43:168463 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528464 ASSERT_TRUE(response);
[email protected]372d34a2008-11-05 21:30:518465
wezca1070932016-05-26 20:30:528466 EXPECT_TRUE(response->headers);
[email protected]372d34a2008-11-05 21:30:518467 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
8468
8469 std::string response_data;
bnc691fda62016-08-12 00:43:168470 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:018471 EXPECT_THAT(rv, IsOk());
[email protected]372d34a2008-11-05 21:30:518472 EXPECT_EQ(kExpectedResponseData[i], response_data);
8473 }
8474}
[email protected]f9ee6b52008-11-08 06:46:238475
8476// Test the request-challenge-retry sequence for basic auth when there is
8477// an identity in the URL. The request should be sent as normal, but when
[email protected]2262e3a2012-05-22 16:08:168478// it fails the identity from the URL is used to answer the challenge.
bncd16676a2016-07-20 16:23:018479TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
[email protected]1c773ea12009-04-28 19:58:428480 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238481 request.method = "GET";
bncce36dca22015-04-21 22:11:238482 request.url = GURL("http://foo:b@[email protected]/");
[email protected]7b08ba62012-02-10 20:19:418483 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:108484 request.traffic_annotation =
8485 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]a97cca42009-08-14 01:00:298486
danakj1fd259a02016-04-16 03:17:098487 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168488 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278489
[email protected]a97cca42009-08-14 01:00:298490 // The password contains an escaped character -- for this test to pass it
8491 // will need to be unescaped by HttpNetworkTransaction.
8492 EXPECT_EQ("b%40r", request.url.password());
8493
[email protected]f9ee6b52008-11-08 06:46:238494 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238495 MockWrite(
8496 "GET / HTTP/1.1\r\n"
8497 "Host: www.example.org\r\n"
8498 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238499 };
8500
8501 MockRead data_reads1[] = {
8502 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8503 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8504 MockRead("Content-Length: 10\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068505 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238506 };
8507
[email protected]2262e3a2012-05-22 16:08:168508 // After the challenge above, the transaction will be restarted using the
8509 // identity from the url (foo, b@r) to answer the challenge.
8510 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238511 MockWrite(
8512 "GET / HTTP/1.1\r\n"
8513 "Host: www.example.org\r\n"
8514 "Connection: keep-alive\r\n"
8515 "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168516 };
8517
8518 MockRead data_reads2[] = {
8519 MockRead("HTTP/1.0 200 OK\r\n"),
8520 MockRead("Content-Length: 100\r\n\r\n"),
8521 MockRead(SYNCHRONOUS, OK),
8522 };
8523
Ryan Sleevib8d7ea02018-05-07 20:01:018524 StaticSocketDataProvider data1(data_reads1, data_writes1);
8525 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078526 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8527 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238528
[email protected]49639fa2011-12-20 23:22:418529 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208530 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018531 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238532 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018533 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168534 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168535
8536 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168537 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018538 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168539 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018540 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168541 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:228542
bnc691fda62016-08-12 00:43:168543 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528544 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168545
8546 // There is no challenge info, since the identity in URL worked.
Emily Starkf2c9bbd2019-04-09 17:08:588547 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]2262e3a2012-05-22 16:08:168548
8549 EXPECT_EQ(100, response->headers->GetContentLength());
8550
8551 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558552 base::RunLoop().RunUntilIdle();
[email protected]2262e3a2012-05-22 16:08:168553}
8554
8555// Test the request-challenge-retry sequence for basic auth when there is an
8556// incorrect identity in the URL. The identity from the URL should be used only
8557// once.
bncd16676a2016-07-20 16:23:018558TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
[email protected]2262e3a2012-05-22 16:08:168559 HttpRequestInfo request;
8560 request.method = "GET";
8561 // Note: the URL has a username:password in it. The password "baz" is
8562 // wrong (should be "bar").
bncce36dca22015-04-21 22:11:238563 request.url = GURL("http://foo:[email protected]/");
[email protected]2262e3a2012-05-22 16:08:168564
8565 request.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:108566 request.traffic_annotation =
8567 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2262e3a2012-05-22 16:08:168568
danakj1fd259a02016-04-16 03:17:098569 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168570 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2262e3a2012-05-22 16:08:168571
8572 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238573 MockWrite(
8574 "GET / HTTP/1.1\r\n"
8575 "Host: www.example.org\r\n"
8576 "Connection: keep-alive\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168577 };
8578
8579 MockRead data_reads1[] = {
8580 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8581 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8582 MockRead("Content-Length: 10\r\n\r\n"),
8583 MockRead(SYNCHRONOUS, ERR_FAILED),
8584 };
8585
8586 // After the challenge above, the transaction will be restarted using the
8587 // identity from the url (foo, baz) to answer the challenge.
8588 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238589 MockWrite(
8590 "GET / HTTP/1.1\r\n"
8591 "Host: www.example.org\r\n"
8592 "Connection: keep-alive\r\n"
8593 "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168594 };
8595
8596 MockRead data_reads2[] = {
8597 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8598 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8599 MockRead("Content-Length: 10\r\n\r\n"),
8600 MockRead(SYNCHRONOUS, ERR_FAILED),
8601 };
8602
8603 // After the challenge above, the transaction will be restarted using the
8604 // identity supplied by the user (foo, bar) to answer the challenge.
8605 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238606 MockWrite(
8607 "GET / HTTP/1.1\r\n"
8608 "Host: www.example.org\r\n"
8609 "Connection: keep-alive\r\n"
8610 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2262e3a2012-05-22 16:08:168611 };
8612
8613 MockRead data_reads3[] = {
8614 MockRead("HTTP/1.0 200 OK\r\n"),
8615 MockRead("Content-Length: 100\r\n\r\n"),
8616 MockRead(SYNCHRONOUS, OK),
8617 };
8618
Ryan Sleevib8d7ea02018-05-07 20:01:018619 StaticSocketDataProvider data1(data_reads1, data_writes1);
8620 StaticSocketDataProvider data2(data_reads2, data_writes2);
8621 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:078622 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8623 session_deps_.socket_factory->AddSocketDataProvider(&data2);
8624 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]2262e3a2012-05-22 16:08:168625
8626 TestCompletionCallback callback1;
8627
tfarina42834112016-09-22 13:38:208628 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018629 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168630
8631 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018632 EXPECT_THAT(rv, IsOk());
[email protected]2262e3a2012-05-22 16:08:168633
bnc691fda62016-08-12 00:43:168634 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168635 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:168636 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:018637 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168638 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018639 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168640 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168641
bnc691fda62016-08-12 00:43:168642 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528643 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:588644 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]2262e3a2012-05-22 16:08:168645
8646 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168647 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018648 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2262e3a2012-05-22 16:08:168649 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018650 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168651 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2262e3a2012-05-22 16:08:168652
bnc691fda62016-08-12 00:43:168653 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528654 ASSERT_TRUE(response);
[email protected]2262e3a2012-05-22 16:08:168655
8656 // There is no challenge info, since the identity worked.
Emily Starkf2c9bbd2019-04-09 17:08:588657 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]2262e3a2012-05-22 16:08:168658
8659 EXPECT_EQ(100, response->headers->GetContentLength());
8660
[email protected]ea9dc9a2009-09-05 00:43:328661 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558662 base::RunLoop().RunUntilIdle();
[email protected]ea9dc9a2009-09-05 00:43:328663}
8664
[email protected]2217aa22013-10-11 03:03:548665
8666// Test the request-challenge-retry sequence for basic auth when there is a
8667// correct identity in the URL, but its use is being suppressed. The identity
8668// from the URL should never be used.
bncd16676a2016-07-20 16:23:018669TEST_F(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
[email protected]2217aa22013-10-11 03:03:548670 HttpRequestInfo request;
8671 request.method = "GET";
bncce36dca22015-04-21 22:11:238672 request.url = GURL("http://foo:[email protected]/");
[email protected]2217aa22013-10-11 03:03:548673 request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
Ramin Halavatib5e433e62018-02-07 07:41:108674 request.traffic_annotation =
8675 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2217aa22013-10-11 03:03:548676
danakj1fd259a02016-04-16 03:17:098677 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:168678 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2217aa22013-10-11 03:03:548679
8680 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238681 MockWrite(
8682 "GET / HTTP/1.1\r\n"
8683 "Host: www.example.org\r\n"
8684 "Connection: keep-alive\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548685 };
8686
8687 MockRead data_reads1[] = {
8688 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8689 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8690 MockRead("Content-Length: 10\r\n\r\n"),
8691 MockRead(SYNCHRONOUS, ERR_FAILED),
8692 };
8693
8694 // After the challenge above, the transaction will be restarted using the
8695 // identity supplied by the user, not the one in the URL, to answer the
8696 // challenge.
8697 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:238698 MockWrite(
8699 "GET / HTTP/1.1\r\n"
8700 "Host: www.example.org\r\n"
8701 "Connection: keep-alive\r\n"
8702 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]2217aa22013-10-11 03:03:548703 };
8704
8705 MockRead data_reads3[] = {
8706 MockRead("HTTP/1.0 200 OK\r\n"),
8707 MockRead("Content-Length: 100\r\n\r\n"),
8708 MockRead(SYNCHRONOUS, OK),
8709 };
8710
Ryan Sleevib8d7ea02018-05-07 20:01:018711 StaticSocketDataProvider data1(data_reads1, data_writes1);
8712 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]2217aa22013-10-11 03:03:548713 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8714 session_deps_.socket_factory->AddSocketDataProvider(&data3);
8715
8716 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:208717 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018718 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548719 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018720 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168721 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548722
bnc691fda62016-08-12 00:43:168723 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528724 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:588725 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]2217aa22013-10-11 03:03:548726
8727 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:168728 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback());
robpercival214763f2016-07-01 23:27:018729 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2217aa22013-10-11 03:03:548730 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:018731 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:168732 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]2217aa22013-10-11 03:03:548733
bnc691fda62016-08-12 00:43:168734 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528735 ASSERT_TRUE(response);
[email protected]2217aa22013-10-11 03:03:548736
8737 // There is no challenge info, since the identity worked.
Emily Starkf2c9bbd2019-04-09 17:08:588738 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]2217aa22013-10-11 03:03:548739 EXPECT_EQ(100, response->headers->GetContentLength());
8740
8741 // Empty the current queue.
fdoray92e35a72016-06-10 15:54:558742 base::RunLoop().RunUntilIdle();
[email protected]2217aa22013-10-11 03:03:548743}
8744
[email protected]f9ee6b52008-11-08 06:46:238745// Test that previously tried username/passwords for a realm get re-used.
bncd16676a2016-07-20 16:23:018746TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
danakj1fd259a02016-04-16 03:17:098747 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]f9ee6b52008-11-08 06:46:238748
8749 // Transaction 1: authenticate (foo, bar) on MyRealm1
8750 {
[email protected]1c773ea12009-04-28 19:58:428751 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238752 request.method = "GET";
bncce36dca22015-04-21 22:11:238753 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e62018-02-07 07:41:108754 request.traffic_annotation =
8755 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238756
bnc691fda62016-08-12 00:43:168757 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278758
[email protected]f9ee6b52008-11-08 06:46:238759 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238760 MockWrite(
8761 "GET /x/y/z HTTP/1.1\r\n"
8762 "Host: www.example.org\r\n"
8763 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238764 };
8765
8766 MockRead data_reads1[] = {
8767 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8768 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8769 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068770 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238771 };
8772
8773 // Resend with authorization (username=foo, password=bar)
8774 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238775 MockWrite(
8776 "GET /x/y/z HTTP/1.1\r\n"
8777 "Host: www.example.org\r\n"
8778 "Connection: keep-alive\r\n"
8779 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238780 };
8781
8782 // Sever accepts the authorization.
8783 MockRead data_reads2[] = {
8784 MockRead("HTTP/1.0 200 OK\r\n"),
8785 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068786 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238787 };
8788
Ryan Sleevib8d7ea02018-05-07 20:01:018789 StaticSocketDataProvider data1(data_reads1, data_writes1);
8790 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078791 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8792 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238793
[email protected]49639fa2011-12-20 23:22:418794 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238795
tfarina42834112016-09-22 13:38:208796 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018797 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238798
8799 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018800 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238801
bnc691fda62016-08-12 00:43:168802 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528803 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:588804 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]f9ee6b52008-11-08 06:46:238805
[email protected]49639fa2011-12-20 23:22:418806 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238807
bnc691fda62016-08-12 00:43:168808 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
8809 callback2.callback());
robpercival214763f2016-07-01 23:27:018810 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238811
8812 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018813 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238814
bnc691fda62016-08-12 00:43:168815 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528816 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:588817 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]f9ee6b52008-11-08 06:46:238818 EXPECT_EQ(100, response->headers->GetContentLength());
8819 }
8820
8821 // ------------------------------------------------------------------------
8822
8823 // Transaction 2: authenticate (foo2, bar2) on MyRealm2
8824 {
[email protected]1c773ea12009-04-28 19:58:428825 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238826 request.method = "GET";
8827 // Note that Transaction 1 was at /x/y/z, so this is in the same
8828 // protection space as MyRealm1.
bncce36dca22015-04-21 22:11:238829 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e62018-02-07 07:41:108830 request.traffic_annotation =
8831 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238832
bnc691fda62016-08-12 00:43:168833 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278834
[email protected]f9ee6b52008-11-08 06:46:238835 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238836 MockWrite(
8837 "GET /x/y/a/b HTTP/1.1\r\n"
8838 "Host: www.example.org\r\n"
8839 "Connection: keep-alive\r\n"
8840 // Send preemptive authorization for MyRealm1
8841 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238842 };
8843
8844 // The server didn't like the preemptive authorization, and
8845 // challenges us for a different realm (MyRealm2).
8846 MockRead data_reads1[] = {
8847 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8848 MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
8849 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068850 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238851 };
8852
8853 // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
8854 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238855 MockWrite(
8856 "GET /x/y/a/b HTTP/1.1\r\n"
8857 "Host: www.example.org\r\n"
8858 "Connection: keep-alive\r\n"
8859 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238860 };
8861
8862 // Sever accepts the authorization.
8863 MockRead data_reads2[] = {
8864 MockRead("HTTP/1.0 200 OK\r\n"),
8865 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068866 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238867 };
8868
Ryan Sleevib8d7ea02018-05-07 20:01:018869 StaticSocketDataProvider data1(data_reads1, data_writes1);
8870 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078871 session_deps_.socket_factory->AddSocketDataProvider(&data1);
8872 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:238873
[email protected]49639fa2011-12-20 23:22:418874 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238875
tfarina42834112016-09-22 13:38:208876 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018877 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238878
8879 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018880 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238881
bnc691fda62016-08-12 00:43:168882 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528883 ASSERT_TRUE(response);
8884 ASSERT_TRUE(response->auth_challenge);
[email protected]79cb5c12011-09-12 13:12:048885 EXPECT_FALSE(response->auth_challenge->is_proxy);
asanka098c0092016-06-16 20:18:438886 EXPECT_EQ("http://www.example.org",
8887 response->auth_challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:048888 EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
aberentbba302d2015-12-03 10:20:198889 EXPECT_EQ(kBasicAuthScheme, response->auth_challenge->scheme);
[email protected]f9ee6b52008-11-08 06:46:238890
[email protected]49639fa2011-12-20 23:22:418891 TestCompletionCallback callback2;
[email protected]f9ee6b52008-11-08 06:46:238892
bnc691fda62016-08-12 00:43:168893 rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2),
8894 callback2.callback());
robpercival214763f2016-07-01 23:27:018895 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238896
8897 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:018898 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238899
bnc691fda62016-08-12 00:43:168900 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528901 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:588902 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]f9ee6b52008-11-08 06:46:238903 EXPECT_EQ(100, response->headers->GetContentLength());
8904 }
8905
8906 // ------------------------------------------------------------------------
8907
8908 // Transaction 3: Resend a request in MyRealm's protection space --
8909 // succeed with preemptive authorization.
8910 {
[email protected]1c773ea12009-04-28 19:58:428911 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238912 request.method = "GET";
bncce36dca22015-04-21 22:11:238913 request.url = GURL("http://www.example.org/x/y/z2");
Ramin Halavatib5e433e62018-02-07 07:41:108914 request.traffic_annotation =
8915 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238916
bnc691fda62016-08-12 00:43:168917 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278918
[email protected]f9ee6b52008-11-08 06:46:238919 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238920 MockWrite(
8921 "GET /x/y/z2 HTTP/1.1\r\n"
8922 "Host: www.example.org\r\n"
8923 "Connection: keep-alive\r\n"
8924 // The authorization for MyRealm1 gets sent preemptively
8925 // (since the url is in the same protection space)
8926 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238927 };
8928
8929 // Sever accepts the preemptive authorization
8930 MockRead data_reads1[] = {
8931 MockRead("HTTP/1.0 200 OK\r\n"),
8932 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068933 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238934 };
8935
Ryan Sleevib8d7ea02018-05-07 20:01:018936 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:078937 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]f9ee6b52008-11-08 06:46:238938
[email protected]49639fa2011-12-20 23:22:418939 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:238940
tfarina42834112016-09-22 13:38:208941 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:018942 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:238943
8944 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:018945 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:238946
bnc691fda62016-08-12 00:43:168947 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:528948 ASSERT_TRUE(response);
[email protected]f9ee6b52008-11-08 06:46:238949
Emily Starkf2c9bbd2019-04-09 17:08:588950 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]f9ee6b52008-11-08 06:46:238951 EXPECT_EQ(100, response->headers->GetContentLength());
8952 }
8953
8954 // ------------------------------------------------------------------------
8955
8956 // Transaction 4: request another URL in MyRealm (however the
8957 // url is not known to belong to the protection space, so no pre-auth).
8958 {
[email protected]1c773ea12009-04-28 19:58:428959 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:238960 request.method = "GET";
bncce36dca22015-04-21 22:11:238961 request.url = GURL("http://www.example.org/x/1");
Ramin Halavatib5e433e62018-02-07 07:41:108962 request.traffic_annotation =
8963 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:238964
bnc691fda62016-08-12 00:43:168965 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:278966
[email protected]f9ee6b52008-11-08 06:46:238967 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:238968 MockWrite(
8969 "GET /x/1 HTTP/1.1\r\n"
8970 "Host: www.example.org\r\n"
8971 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238972 };
8973
8974 MockRead data_reads1[] = {
8975 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
8976 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
8977 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068978 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:238979 };
8980
8981 // Resend with authorization from MyRealm's cache.
8982 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:238983 MockWrite(
8984 "GET /x/1 HTTP/1.1\r\n"
8985 "Host: www.example.org\r\n"
8986 "Connection: keep-alive\r\n"
8987 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:238988 };
8989
8990 // Sever accepts the authorization.
8991 MockRead data_reads2[] = {
8992 MockRead("HTTP/1.0 200 OK\r\n"),
8993 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:068994 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:238995 };
8996
Ryan Sleevib8d7ea02018-05-07 20:01:018997 StaticSocketDataProvider data1(data_reads1, data_writes1);
8998 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:078999 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9000 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]f9ee6b52008-11-08 06:46:239001
[email protected]49639fa2011-12-20 23:22:419002 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239003
tfarina42834112016-09-22 13:38:209004 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019005 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239006
9007 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019008 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239009
bnc691fda62016-08-12 00:43:169010 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419011 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169012 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019013 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229014 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019015 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169016 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229017
bnc691fda62016-08-12 00:43:169018 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529019 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:589020 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]f9ee6b52008-11-08 06:46:239021 EXPECT_EQ(100, response->headers->GetContentLength());
9022 }
9023
9024 // ------------------------------------------------------------------------
9025
9026 // Transaction 5: request a URL in MyRealm, but the server rejects the
9027 // cached identity. Should invalidate and re-prompt.
9028 {
[email protected]1c773ea12009-04-28 19:58:429029 HttpRequestInfo request;
[email protected]f9ee6b52008-11-08 06:46:239030 request.method = "GET";
bncce36dca22015-04-21 22:11:239031 request.url = GURL("http://www.example.org/p/q/t");
Ramin Halavatib5e433e62018-02-07 07:41:109032 request.traffic_annotation =
9033 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]f9ee6b52008-11-08 06:46:239034
bnc691fda62016-08-12 00:43:169035 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279036
[email protected]f9ee6b52008-11-08 06:46:239037 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239038 MockWrite(
9039 "GET /p/q/t HTTP/1.1\r\n"
9040 "Host: www.example.org\r\n"
9041 "Connection: keep-alive\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239042 };
9043
9044 MockRead data_reads1[] = {
9045 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9046 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9047 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069048 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239049 };
9050
9051 // Resend with authorization from cache for MyRealm.
9052 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239053 MockWrite(
9054 "GET /p/q/t HTTP/1.1\r\n"
9055 "Host: www.example.org\r\n"
9056 "Connection: keep-alive\r\n"
9057 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239058 };
9059
9060 // Sever rejects the authorization.
9061 MockRead data_reads2[] = {
9062 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9063 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
9064 MockRead("Content-Length: 10000\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069065 MockRead(SYNCHRONOUS, ERR_FAILED),
[email protected]f9ee6b52008-11-08 06:46:239066 };
9067
9068 // At this point we should prompt for new credentials for MyRealm.
9069 // Restart with username=foo3, password=foo4.
9070 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:239071 MockWrite(
9072 "GET /p/q/t HTTP/1.1\r\n"
9073 "Host: www.example.org\r\n"
9074 "Connection: keep-alive\r\n"
9075 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
[email protected]f9ee6b52008-11-08 06:46:239076 };
9077
9078 // Sever accepts the authorization.
9079 MockRead data_reads3[] = {
9080 MockRead("HTTP/1.0 200 OK\r\n"),
9081 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069082 MockRead(SYNCHRONOUS, OK),
[email protected]f9ee6b52008-11-08 06:46:239083 };
9084
Ryan Sleevib8d7ea02018-05-07 20:01:019085 StaticSocketDataProvider data1(data_reads1, data_writes1);
9086 StaticSocketDataProvider data2(data_reads2, data_writes2);
9087 StaticSocketDataProvider data3(data_reads3, data_writes3);
[email protected]bb88e1d32013-05-03 23:11:079088 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9089 session_deps_.socket_factory->AddSocketDataProvider(&data2);
9090 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]f9ee6b52008-11-08 06:46:239091
[email protected]49639fa2011-12-20 23:22:419092 TestCompletionCallback callback1;
[email protected]f9ee6b52008-11-08 06:46:239093
tfarina42834112016-09-22 13:38:209094 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019095 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239096
9097 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019098 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239099
bnc691fda62016-08-12 00:43:169100 EXPECT_TRUE(trans.IsReadyToRestartForAuth());
[email protected]49639fa2011-12-20 23:22:419101 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:169102 rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback());
robpercival214763f2016-07-01 23:27:019103 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0757e7702009-03-27 04:00:229104 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019105 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169106 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]0757e7702009-03-27 04:00:229107
bnc691fda62016-08-12 00:43:169108 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529109 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:589110 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]f9ee6b52008-11-08 06:46:239111
[email protected]49639fa2011-12-20 23:22:419112 TestCompletionCallback callback3;
[email protected]f9ee6b52008-11-08 06:46:239113
bnc691fda62016-08-12 00:43:169114 rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3),
9115 callback3.callback());
robpercival214763f2016-07-01 23:27:019116 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]f9ee6b52008-11-08 06:46:239117
[email protected]0757e7702009-03-27 04:00:229118 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:019119 EXPECT_THAT(rv, IsOk());
[email protected]f9ee6b52008-11-08 06:46:239120
bnc691fda62016-08-12 00:43:169121 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529122 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:589123 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]f9ee6b52008-11-08 06:46:239124 EXPECT_EQ(100, response->headers->GetContentLength());
9125 }
9126}
[email protected]89ceba9a2009-03-21 03:46:069127
[email protected]3c32c5f2010-05-18 15:18:129128// Tests that nonce count increments when multiple auth attempts
9129// are started with the same nonce.
bncd16676a2016-07-20 16:23:019130TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
[email protected]54fea2562010-11-17 14:40:449131 HttpAuthHandlerDigest::Factory* digest_factory =
9132 new HttpAuthHandlerDigest::Factory();
9133 HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
9134 new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
9135 digest_factory->set_nonce_generator(nonce_generator);
[email protected]bb88e1d32013-05-03 23:11:079136 session_deps_.http_auth_handler_factory.reset(digest_factory);
danakj1fd259a02016-04-16 03:17:099137 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3c32c5f2010-05-18 15:18:129138
9139 // Transaction 1: authenticate (foo, bar) on MyRealm1
9140 {
[email protected]3c32c5f2010-05-18 15:18:129141 HttpRequestInfo request;
9142 request.method = "GET";
bncce36dca22015-04-21 22:11:239143 request.url = GURL("http://www.example.org/x/y/z");
Ramin Halavatib5e433e62018-02-07 07:41:109144 request.traffic_annotation =
9145 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129146
bnc691fda62016-08-12 00:43:169147 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279148
[email protected]3c32c5f2010-05-18 15:18:129149 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239150 MockWrite(
9151 "GET /x/y/z HTTP/1.1\r\n"
9152 "Host: www.example.org\r\n"
9153 "Connection: keep-alive\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129154 };
9155
9156 MockRead data_reads1[] = {
9157 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
9158 MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
9159 "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069160 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129161 };
9162
9163 // Resend with authorization (username=foo, password=bar)
9164 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:239165 MockWrite(
9166 "GET /x/y/z HTTP/1.1\r\n"
9167 "Host: www.example.org\r\n"
9168 "Connection: keep-alive\r\n"
9169 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9170 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
9171 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
9172 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129173 };
9174
9175 // Sever accepts the authorization.
9176 MockRead data_reads2[] = {
zmo9528c9f42015-08-04 22:12:089177 MockRead("HTTP/1.0 200 OK\r\n"),
9178 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129179 };
9180
Ryan Sleevib8d7ea02018-05-07 20:01:019181 StaticSocketDataProvider data1(data_reads1, data_writes1);
9182 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:079183 session_deps_.socket_factory->AddSocketDataProvider(&data1);
9184 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]3c32c5f2010-05-18 15:18:129185
[email protected]49639fa2011-12-20 23:22:419186 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129187
tfarina42834112016-09-22 13:38:209188 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019189 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129190
9191 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019192 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129193
bnc691fda62016-08-12 00:43:169194 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529195 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:589196 EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge));
[email protected]3c32c5f2010-05-18 15:18:129197
[email protected]49639fa2011-12-20 23:22:419198 TestCompletionCallback callback2;
[email protected]3c32c5f2010-05-18 15:18:129199
bnc691fda62016-08-12 00:43:169200 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar),
9201 callback2.callback());
robpercival214763f2016-07-01 23:27:019202 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129203
9204 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019205 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129206
bnc691fda62016-08-12 00:43:169207 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529208 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:589209 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]3c32c5f2010-05-18 15:18:129210 }
9211
9212 // ------------------------------------------------------------------------
9213
9214 // Transaction 2: Request another resource in digestive's protection space.
9215 // This will preemptively add an Authorization header which should have an
9216 // "nc" value of 2 (as compared to 1 in the first use.
9217 {
[email protected]3c32c5f2010-05-18 15:18:129218 HttpRequestInfo request;
9219 request.method = "GET";
9220 // Note that Transaction 1 was at /x/y/z, so this is in the same
9221 // protection space as digest.
bncce36dca22015-04-21 22:11:239222 request.url = GURL("http://www.example.org/x/y/a/b");
Ramin Halavatib5e433e62018-02-07 07:41:109223 request.traffic_annotation =
9224 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3c32c5f2010-05-18 15:18:129225
bnc691fda62016-08-12 00:43:169226 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279227
[email protected]3c32c5f2010-05-18 15:18:129228 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:239229 MockWrite(
9230 "GET /x/y/a/b HTTP/1.1\r\n"
9231 "Host: www.example.org\r\n"
9232 "Connection: keep-alive\r\n"
9233 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
9234 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
9235 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
9236 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
[email protected]3c32c5f2010-05-18 15:18:129237 };
9238
9239 // Sever accepts the authorization.
9240 MockRead data_reads1[] = {
9241 MockRead("HTTP/1.0 200 OK\r\n"),
9242 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069243 MockRead(SYNCHRONOUS, OK),
[email protected]3c32c5f2010-05-18 15:18:129244 };
9245
Ryan Sleevib8d7ea02018-05-07 20:01:019246 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:079247 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]3c32c5f2010-05-18 15:18:129248
[email protected]49639fa2011-12-20 23:22:419249 TestCompletionCallback callback1;
[email protected]3c32c5f2010-05-18 15:18:129250
tfarina42834112016-09-22 13:38:209251 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019252 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3c32c5f2010-05-18 15:18:129253
9254 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019255 EXPECT_THAT(rv, IsOk());
[email protected]3c32c5f2010-05-18 15:18:129256
bnc691fda62016-08-12 00:43:169257 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:529258 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:589259 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]3c32c5f2010-05-18 15:18:129260 }
9261}
9262
[email protected]89ceba9a2009-03-21 03:46:069263// Test the ResetStateForRestart() private method.
bncd16676a2016-07-20 16:23:019264TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
[email protected]89ceba9a2009-03-21 03:46:069265 // Create a transaction (the dependencies aren't important).
danakj1fd259a02016-04-16 03:17:099266 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169267 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]89ceba9a2009-03-21 03:46:069268
9269 // Setup some state (which we expect ResetStateForRestart() will clear).
Victor Costan9c7302b2018-08-27 16:39:449270 trans.read_buf_ = base::MakeRefCounted<IOBuffer>(15);
bnc691fda62016-08-12 00:43:169271 trans.read_buf_len_ = 15;
9272 trans.request_headers_.SetHeader("Authorization", "NTLM");
[email protected]89ceba9a2009-03-21 03:46:069273
9274 // Setup state in response_
bnc691fda62016-08-12 00:43:169275 HttpResponseInfo* response = &trans.response_;
Emily Starkf2c9bbd2019-04-09 17:08:589276 response->auth_challenge = base::nullopt;
[email protected]70d66502011-09-23 00:55:089277 response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical.
[email protected]0877e3d2009-10-17 22:29:579278 response->response_time = base::Time::Now();
9279 response->was_cached = true; // (Wouldn't ever actually be true...)
[email protected]89ceba9a2009-03-21 03:46:069280
9281 { // Setup state for response_.vary_data
9282 HttpRequestInfo request;
9283 std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
9284 std::replace(temp.begin(), temp.end(), '\n', '\0');
[email protected]ad8e04a2010-11-01 04:16:279285 scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
[email protected]8c76ae22010-04-20 22:15:439286 request.extra_headers.SetHeader("Foo", "1");
9287 request.extra_headers.SetHeader("bar", "23");
[email protected]90499482013-06-01 00:39:509288 EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
[email protected]89ceba9a2009-03-21 03:46:069289 }
9290
9291 // Cause the above state to be reset.
bnc691fda62016-08-12 00:43:169292 trans.ResetStateForRestart();
[email protected]89ceba9a2009-03-21 03:46:069293
9294 // Verify that the state that needed to be reset, has been reset.
bnc691fda62016-08-12 00:43:169295 EXPECT_FALSE(trans.read_buf_);
9296 EXPECT_EQ(0, trans.read_buf_len_);
9297 EXPECT_TRUE(trans.request_headers_.IsEmpty());
Emily Starkf2c9bbd2019-04-09 17:08:589298 EXPECT_FALSE(response->auth_challenge.has_value());
wezca1070932016-05-26 20:30:529299 EXPECT_FALSE(response->headers);
[email protected]34f40942010-10-04 00:34:049300 EXPECT_FALSE(response->was_cached);
[email protected]70d66502011-09-23 00:55:089301 EXPECT_EQ(0U, response->ssl_info.cert_status);
[email protected]0877e3d2009-10-17 22:29:579302 EXPECT_FALSE(response->vary_data.is_valid());
[email protected]89ceba9a2009-03-21 03:46:069303}
9304
[email protected]bacff652009-03-31 17:50:339305// Test HTTPS connections to a site with a bad certificate
bncd16676a2016-07-20 16:23:019306TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
[email protected]bacff652009-03-31 17:50:339307 HttpRequestInfo request;
9308 request.method = "GET";
bncce36dca22015-04-21 22:11:239309 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109310 request.traffic_annotation =
9311 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339312
danakj1fd259a02016-04-16 03:17:099313 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169314 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:279315
[email protected]bacff652009-03-31 17:50:339316 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:239317 MockWrite(
9318 "GET / HTTP/1.1\r\n"
9319 "Host: www.example.org\r\n"
9320 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339321 };
9322
9323 MockRead data_reads[] = {
9324 MockRead("HTTP/1.0 200 OK\r\n"),
9325 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9326 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069327 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339328 };
9329
[email protected]5ecc992a42009-11-11 01:41:599330 StaticSocketDataProvider ssl_bad_certificate;
Ryan Sleevib8d7ea02018-05-07 20:01:019331 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069332 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9333 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339334
[email protected]bb88e1d32013-05-03 23:11:079335 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9336 session_deps_.socket_factory->AddSocketDataProvider(&data);
9337 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9338 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339339
[email protected]49639fa2011-12-20 23:22:419340 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339341
tfarina42834112016-09-22 13:38:209342 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019343 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339344
9345 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019346 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339347
bnc691fda62016-08-12 00:43:169348 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019349 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339350
9351 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019352 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:339353
bnc691fda62016-08-12 00:43:169354 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339355
wezca1070932016-05-26 20:30:529356 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339357 EXPECT_EQ(100, response->headers->GetContentLength());
9358}
9359
9360// Test HTTPS connections to a site with a bad certificate, going through a
9361// proxy
bncd16676a2016-07-20 16:23:019362TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499363 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9364 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339365
9366 HttpRequestInfo request;
9367 request.method = "GET";
bncce36dca22015-04-21 22:11:239368 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109369 request.traffic_annotation =
9370 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]bacff652009-03-31 17:50:339371
9372 MockWrite proxy_writes[] = {
rsleevidb16bb02015-11-12 23:47:179373 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9374 "Host: www.example.org:443\r\n"
9375 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339376 };
9377
9378 MockRead proxy_reads[] = {
9379 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069380 MockRead(SYNCHRONOUS, OK)
[email protected]bacff652009-03-31 17:50:339381 };
9382
9383 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179384 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9385 "Host: www.example.org:443\r\n"
9386 "Proxy-Connection: keep-alive\r\n\r\n"),
9387 MockWrite("GET / HTTP/1.1\r\n"
9388 "Host: www.example.org\r\n"
9389 "Connection: keep-alive\r\n\r\n"),
[email protected]bacff652009-03-31 17:50:339390 };
9391
9392 MockRead data_reads[] = {
9393 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9394 MockRead("HTTP/1.0 200 OK\r\n"),
9395 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9396 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069397 MockRead(SYNCHRONOUS, OK),
[email protected]bacff652009-03-31 17:50:339398 };
9399
Ryan Sleevib8d7ea02018-05-07 20:01:019400 StaticSocketDataProvider ssl_bad_certificate(proxy_reads, proxy_writes);
9401 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069402 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
9403 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bacff652009-03-31 17:50:339404
[email protected]bb88e1d32013-05-03 23:11:079405 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
9406 session_deps_.socket_factory->AddSocketDataProvider(&data);
9407 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
9408 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]bacff652009-03-31 17:50:339409
[email protected]49639fa2011-12-20 23:22:419410 TestCompletionCallback callback;
[email protected]bacff652009-03-31 17:50:339411
9412 for (int i = 0; i < 2; i++) {
[email protected]bb88e1d32013-05-03 23:11:079413 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]bacff652009-03-31 17:50:339414
danakj1fd259a02016-04-16 03:17:099415 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169416 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bacff652009-03-31 17:50:339417
tfarina42834112016-09-22 13:38:209418 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019419 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339420
9421 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019422 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]bacff652009-03-31 17:50:339423
bnc691fda62016-08-12 00:43:169424 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:019425 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bacff652009-03-31 17:50:339426
9427 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019428 EXPECT_THAT(rv, IsOk());
[email protected]bacff652009-03-31 17:50:339429
bnc691fda62016-08-12 00:43:169430 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]bacff652009-03-31 17:50:339431
wezca1070932016-05-26 20:30:529432 ASSERT_TRUE(response);
[email protected]bacff652009-03-31 17:50:339433 EXPECT_EQ(100, response->headers->GetContentLength());
9434 }
9435}
9436
[email protected]2df19bb2010-08-25 20:13:469437
9438// Test HTTPS connections to a site, going through an HTTPS proxy
bncd16676a2016-07-20 16:23:019439TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599440 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499441 ProxyResolutionService::CreateFixedFromPacResult(
9442 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519443 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079444 session_deps_.net_log = &net_log;
[email protected]2df19bb2010-08-25 20:13:469445
9446 HttpRequestInfo request;
9447 request.method = "GET";
bncce36dca22015-04-21 22:11:239448 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109449 request.traffic_annotation =
9450 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:469451
9452 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179453 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9454 "Host: www.example.org:443\r\n"
9455 "Proxy-Connection: keep-alive\r\n\r\n"),
9456 MockWrite("GET / HTTP/1.1\r\n"
9457 "Host: www.example.org\r\n"
9458 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:469459 };
9460
9461 MockRead data_reads[] = {
9462 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
9463 MockRead("HTTP/1.1 200 OK\r\n"),
9464 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
9465 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:069466 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:469467 };
9468
Ryan Sleevib8d7ea02018-05-07 20:01:019469 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069470 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9471 SSLSocketDataProvider tunnel_ssl(ASYNC, OK); // SSL through the tunnel
[email protected]2df19bb2010-08-25 20:13:469472
[email protected]bb88e1d32013-05-03 23:11:079473 session_deps_.socket_factory->AddSocketDataProvider(&data);
9474 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9475 session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
[email protected]2df19bb2010-08-25 20:13:469476
[email protected]49639fa2011-12-20 23:22:419477 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:469478
danakj1fd259a02016-04-16 03:17:099479 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169480 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:469481
tfarina42834112016-09-22 13:38:209482 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019483 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:469484
9485 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019486 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:169487 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:469488
wezca1070932016-05-26 20:30:529489 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:469490
tbansal2ecbbc72016-10-06 17:15:479491 EXPECT_TRUE(response->proxy_server.is_https());
[email protected]2df19bb2010-08-25 20:13:469492 EXPECT_TRUE(response->headers->IsKeepAlive());
9493 EXPECT_EQ(200, response->headers->response_code());
9494 EXPECT_EQ(100, response->headers->GetContentLength());
9495 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:209496
9497 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:169498 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:209499 TestLoadTimingNotReusedWithPac(load_timing_info,
9500 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]2df19bb2010-08-25 20:13:469501}
9502
Eric Roman695a7872019-04-16 21:53:299503// Test that an HTTPS Proxy cannot redirect a CONNECT request for main frames.
bncd16676a2016-07-20 16:23:019504TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
Lily Houghton8c2f97d2018-01-22 05:06:599505 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499506 ProxyResolutionService::CreateFixedFromPacResult(
9507 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519508 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:079509 session_deps_.net_log = &net_log;
[email protected]511f6f52010-12-17 03:58:299510
Matt Menkeecfecfc72019-02-05 19:15:289511 const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4);
9512 session_deps_.host_resolver->set_ondemand_mode(true);
9513
[email protected]511f6f52010-12-17 03:58:299514 HttpRequestInfo request;
Eric Roman74103c72019-02-21 00:23:129515 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
[email protected]511f6f52010-12-17 03:58:299516 request.method = "GET";
bncce36dca22015-04-21 22:11:239517 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109518 request.traffic_annotation =
9519 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299520
9521 MockWrite data_writes[] = {
Matt Menkeecfecfc72019-02-05 19:15:289522 MockWrite(ASYNC, 0,
9523 "CONNECT www.example.org:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:179524 "Host: www.example.org:443\r\n"
9525 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299526 };
9527
9528 MockRead data_reads[] = {
Matt Menkeecfecfc72019-02-05 19:15:289529 // Pause on first read.
9530 MockRead(ASYNC, ERR_IO_PENDING, 1),
9531 MockRead(ASYNC, 2, "HTTP/1.1 302 Redirect\r\n"),
9532 MockRead(ASYNC, 3, "Location: http://login.example.com/\r\n"),
9533 MockRead(ASYNC, 4, "Content-Length: 0\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299534 };
9535
Matt Menkeecfecfc72019-02-05 19:15:289536 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069537 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299538
[email protected]bb88e1d32013-05-03 23:11:079539 session_deps_.socket_factory->AddSocketDataProvider(&data);
9540 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299541
[email protected]49639fa2011-12-20 23:22:419542 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299543
danakj1fd259a02016-04-16 03:17:099544 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169545 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299546
tfarina42834112016-09-22 13:38:209547 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019548 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkeecfecfc72019-02-05 19:15:289549 EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
9550
9551 // Host resolution takes |kTimeIncrement|.
9552 FastForwardBy(kTimeIncrement);
9553 // Resolving the current request with |ResolveNow| will cause the pending
9554 // request to instantly complete, and the async connect will start as well.
9555 session_deps_.host_resolver->ResolveOnlyRequestNow();
9556
9557 // Connecting takes |kTimeIncrement|.
9558 FastForwardBy(kTimeIncrement);
9559 data.RunUntilPaused();
9560
9561 // The server takes |kTimeIncrement| to respond.
9562 FastForwardBy(kTimeIncrement);
9563 data.Resume();
[email protected]511f6f52010-12-17 03:58:299564
9565 rv = callback.WaitForResult();
Eric Roman96c5b292019-04-23 18:04:599566 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299567}
9568
Eric Roman74103c72019-02-21 00:23:129569// Test that an HTTPS Proxy cannot redirect a CONNECT request for subresources.
9570TEST_F(HttpNetworkTransactionTest,
9571 RedirectOfHttpsConnectSubresourceViaHttpsProxy) {
9572 base::HistogramTester histograms;
9573 session_deps_.proxy_resolution_service =
9574 ProxyResolutionService::CreateFixedFromPacResult(
9575 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9576 TestNetLog net_log;
9577 session_deps_.net_log = &net_log;
9578
9579 HttpRequestInfo request;
9580 request.method = "GET";
9581 request.url = GURL("https://www.example.org/");
9582 request.traffic_annotation =
9583 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9584
9585 MockWrite data_writes[] = {
9586 MockWrite(ASYNC, 0,
9587 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9588 "Host: www.example.org:443\r\n"
9589 "Proxy-Connection: keep-alive\r\n\r\n"),
9590 };
9591
9592 MockRead data_reads[] = {
9593 MockRead(ASYNC, 1, "HTTP/1.1 302 Redirect\r\n"),
9594 MockRead(ASYNC, 2, "Location: http://login.example.com/\r\n"),
9595 MockRead(ASYNC, 3, "Content-Length: 0\r\n\r\n"),
9596 };
9597
9598 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
9599 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9600
9601 session_deps_.socket_factory->AddSocketDataProvider(&data);
9602 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9603
9604 TestCompletionCallback callback;
9605
9606 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9607 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9608
9609 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
9610 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9611
9612 rv = callback.WaitForResult();
Eric Roman96c5b292019-04-23 18:04:599613 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
Eric Roman74103c72019-02-21 00:23:129614}
9615
9616// Test that an HTTPS Proxy which was auto-detected cannot redirect a CONNECT
9617// request for main frames.
9618TEST_F(HttpNetworkTransactionTest,
9619 RedirectOfHttpsConnectViaAutoDetectedHttpsProxy) {
9620 base::HistogramTester histograms;
9621 session_deps_.proxy_resolution_service =
9622 ProxyResolutionService::CreateFixedFromAutoDetectedPacResult(
9623 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
9624 TestNetLog net_log;
9625 session_deps_.net_log = &net_log;
9626
9627 HttpRequestInfo request;
9628 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
9629 request.method = "GET";
9630 request.url = GURL("https://www.example.org/");
9631 request.traffic_annotation =
9632 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
9633
9634 MockWrite data_writes[] = {
9635 MockWrite(ASYNC, 0,
9636 "CONNECT www.example.org:443 HTTP/1.1\r\n"
9637 "Host: www.example.org:443\r\n"
9638 "Proxy-Connection: keep-alive\r\n\r\n"),
9639 };
9640
9641 MockRead data_reads[] = {
9642 MockRead(ASYNC, 1, "HTTP/1.1 302 Redirect\r\n"),
9643 MockRead(ASYNC, 2, "Location: http://login.example.com/\r\n"),
9644 MockRead(ASYNC, 3, "Content-Length: 0\r\n\r\n"),
9645 };
9646
9647 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
9648 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
9649
9650 session_deps_.socket_factory->AddSocketDataProvider(&data);
9651 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
9652
9653 TestCompletionCallback callback;
9654
9655 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
9656 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
9657
9658 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
9659 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
9660
9661 rv = callback.WaitForResult();
Eric Roman96c5b292019-04-23 18:04:599662 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
Eric Roman74103c72019-02-21 00:23:129663}
9664
Eric Roman695a7872019-04-16 21:53:299665// Tests that an HTTPS (SPDY) Proxy's cannot redirect a CONNECT request for main
Eric Roman74103c72019-02-21 00:23:129666// frames.
bncd16676a2016-07-20 16:23:019667TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
Eric Roman74103c72019-02-21 00:23:129668 base::HistogramTester histograms;
Ramin Halavatica8d5252018-03-12 05:33:499669 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9670 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Matt Menkeecfecfc72019-02-05 19:15:289671 TestNetLog net_log;
9672 session_deps_.net_log = &net_log;
9673
Matt Menkeecfecfc72019-02-05 19:15:289674 const base::TimeDelta kTimeIncrement = base::TimeDelta::FromSeconds(4);
9675 session_deps_.host_resolver->set_ondemand_mode(true);
[email protected]511f6f52010-12-17 03:58:299676
9677 HttpRequestInfo request;
9678 request.method = "GET";
Eric Roman74103c72019-02-21 00:23:129679 request.load_flags = LOAD_MAIN_FRAME_DEPRECATED;
bncce36dca22015-04-21 22:11:239680 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109681 request.traffic_annotation =
9682 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299683
Ryan Hamilton0239aac2018-05-19 00:03:139684 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049685 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9686 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139687 spdy::SpdySerializedFrame goaway(
9688 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299689 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419690 CreateMockWrite(conn, 0, SYNCHRONOUS),
Matt Menkeecfecfc72019-02-05 19:15:289691 CreateMockWrite(goaway, 3, SYNCHRONOUS),
[email protected]511f6f52010-12-17 03:58:299692 };
9693
9694 static const char* const kExtraHeaders[] = {
9695 "location",
9696 "http://login.example.com/",
9697 };
Ryan Hamilton0239aac2018-05-19 00:03:139698 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249699 "302", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
[email protected]511f6f52010-12-17 03:58:299700 MockRead data_reads[] = {
Matt Menkeecfecfc72019-02-05 19:15:289701 // Pause on first read.
9702 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp, 2),
9703 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:299704 };
9705
Matt Menkeecfecfc72019-02-05 19:15:289706 SequencedSocketData data(MockConnect(ASYNC, OK), data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069707 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369708 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299709
[email protected]bb88e1d32013-05-03 23:11:079710 session_deps_.socket_factory->AddSocketDataProvider(&data);
9711 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299712
[email protected]49639fa2011-12-20 23:22:419713 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299714
danakj1fd259a02016-04-16 03:17:099715 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169716 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299717
tfarina42834112016-09-22 13:38:209718 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019719 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Matt Menkeecfecfc72019-02-05 19:15:289720 EXPECT_TRUE(session_deps_.host_resolver->has_pending_requests());
[email protected]511f6f52010-12-17 03:58:299721
Matt Menkeecfecfc72019-02-05 19:15:289722 // Host resolution takes |kTimeIncrement|.
9723 FastForwardBy(kTimeIncrement);
9724 // Resolving the current request with |ResolveNow| will cause the pending
9725 // request to instantly complete, and the async connect will start as well.
9726 session_deps_.host_resolver->ResolveOnlyRequestNow();
9727
9728 // Connecting takes |kTimeIncrement|.
9729 FastForwardBy(kTimeIncrement);
9730 data.RunUntilPaused();
9731
9732 FastForwardBy(kTimeIncrement);
9733 data.Resume();
[email protected]511f6f52010-12-17 03:58:299734 rv = callback.WaitForResult();
Eric Roman96c5b292019-04-23 18:04:599735 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299736}
9737
[email protected]4eddbc732012-08-09 05:40:179738// Test that an HTTPS proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019739TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499740 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9741 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299742
9743 HttpRequestInfo request;
9744 request.method = "GET";
bncce36dca22015-04-21 22:11:239745 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109746 request.traffic_annotation =
9747 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299748
9749 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:179750 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
9751 "Host: www.example.org:443\r\n"
9752 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]511f6f52010-12-17 03:58:299753 };
9754
9755 MockRead data_reads[] = {
9756 MockRead("HTTP/1.1 404 Not Found\r\n"),
9757 MockRead("Content-Length: 23\r\n\r\n"),
9758 MockRead("The host does not exist"),
[email protected]8ddf8322012-02-23 18:08:069759 MockRead(SYNCHRONOUS, OK),
[email protected]511f6f52010-12-17 03:58:299760 };
9761
Ryan Sleevib8d7ea02018-05-07 20:01:019762 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069763 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
[email protected]511f6f52010-12-17 03:58:299764
[email protected]bb88e1d32013-05-03 23:11:079765 session_deps_.socket_factory->AddSocketDataProvider(&data);
9766 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299767
[email protected]49639fa2011-12-20 23:22:419768 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299769
danakj1fd259a02016-04-16 03:17:099770 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169771 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299772
tfarina42834112016-09-22 13:38:209773 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019774 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299775
9776 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019777 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299778
ttuttle960fcbf2016-04-19 13:26:329779 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299780}
9781
[email protected]4eddbc732012-08-09 05:40:179782// Test that a SPDY proxy's response to a CONNECT request is filtered.
bncd16676a2016-07-20 16:23:019783TEST_F(HttpNetworkTransactionTest, ErrorResponseToHttpsConnectViaSpdyProxy) {
Ramin Halavatica8d5252018-03-12 05:33:499784 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
9785 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299786
9787 HttpRequestInfo request;
9788 request.method = "GET";
bncce36dca22015-04-21 22:11:239789 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:109790 request.traffic_annotation =
9791 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]511f6f52010-12-17 03:58:299792
Ryan Hamilton0239aac2018-05-19 00:03:139793 spdy::SpdySerializedFrame conn(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049794 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9795 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139796 spdy::SpdySerializedFrame rst(
9797 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
[email protected]511f6f52010-12-17 03:58:299798 MockWrite data_writes[] = {
bncdf80d44fd2016-07-15 20:27:419799 CreateMockWrite(conn, 0), CreateMockWrite(rst, 3),
[email protected]511f6f52010-12-17 03:58:299800 };
9801
9802 static const char* const kExtraHeaders[] = {
9803 "location",
9804 "http://login.example.com/",
9805 };
Ryan Hamilton0239aac2018-05-19 00:03:139806 spdy::SpdySerializedFrame resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249807 "404", kExtraHeaders, base::size(kExtraHeaders) / 2, 1));
Ryan Hamilton0239aac2018-05-19 00:03:139808 spdy::SpdySerializedFrame body(
Bence Békyd74f4382018-02-20 18:26:199809 spdy_util_.ConstructSpdyDataFrame(1, "The host does not exist", true));
[email protected]511f6f52010-12-17 03:58:299810 MockRead data_reads[] = {
bncdf80d44fd2016-07-15 20:27:419811 CreateMockRead(resp, 1), CreateMockRead(body, 2),
rch8e6c6c42015-05-01 14:05:139812 MockRead(ASYNC, 0, 4), // EOF
[email protected]511f6f52010-12-17 03:58:299813 };
9814
Ryan Sleevib8d7ea02018-05-07 20:01:019815 SequencedSocketData data(data_reads, data_writes);
[email protected]8ddf8322012-02-23 18:08:069816 SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy
bnc3cf2a592016-08-11 14:48:369817 proxy_ssl.next_proto = kProtoHTTP2;
[email protected]511f6f52010-12-17 03:58:299818
[email protected]bb88e1d32013-05-03 23:11:079819 session_deps_.socket_factory->AddSocketDataProvider(&data);
9820 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
[email protected]511f6f52010-12-17 03:58:299821
[email protected]49639fa2011-12-20 23:22:419822 TestCompletionCallback callback;
[email protected]511f6f52010-12-17 03:58:299823
danakj1fd259a02016-04-16 03:17:099824 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:169825 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]511f6f52010-12-17 03:58:299826
tfarina42834112016-09-22 13:38:209827 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:019828 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]511f6f52010-12-17 03:58:299829
9830 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:019831 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]511f6f52010-12-17 03:58:299832
ttuttle960fcbf2016-04-19 13:26:329833 // TODO(juliatuttle): Anything else to check here?
[email protected]511f6f52010-12-17 03:58:299834}
9835
[email protected]0c5fb722012-02-28 11:50:359836// Test the request-challenge-retry sequence for basic auth, through
9837// a SPDY proxy over a single SPDY session.
bncd16676a2016-07-20 16:23:019838TEST_F(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
[email protected]0c5fb722012-02-28 11:50:359839 HttpRequestInfo request;
9840 request.method = "GET";
bncce36dca22015-04-21 22:11:239841 request.url = GURL("https://www.example.org/");
[email protected]0c5fb722012-02-28 11:50:359842 // when the no authentication data flag is set.
ttuttle859dc7a2015-04-23 19:42:299843 request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA;
Ramin Halavatib5e433e62018-02-07 07:41:109844 request.traffic_annotation =
9845 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0c5fb722012-02-28 11:50:359846
9847 // Configure against https proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:599848 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499849 ProxyResolutionService::CreateFixedFromPacResult(
9850 "HTTPS myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:519851 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:079852 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:099853 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0c5fb722012-02-28 11:50:359854
9855 // Since we have proxy, should try to establish tunnel.
Ryan Hamilton0239aac2018-05-19 00:03:139856 spdy::SpdySerializedFrame req(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049857 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
9858 HostPortPair("www.example.org", 443)));
Ryan Hamilton0239aac2018-05-19 00:03:139859 spdy::SpdySerializedFrame rst(
9860 spdy_util_.ConstructSpdyRstStream(1, spdy::ERROR_CODE_CANCEL));
rdsmithebb50aa2015-11-12 03:44:389861 spdy_util_.UpdateWithStreamDestruction(1);
[email protected]0c5fb722012-02-28 11:50:359862
bnc691fda62016-08-12 00:43:169863 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0c5fb722012-02-28 11:50:359864 // be issuing -- the final header line contains the credentials.
9865 const char* const kAuthCredentials[] = {
9866 "proxy-authorization", "Basic Zm9vOmJhcg==",
9867 };
Ryan Hamilton0239aac2018-05-19 00:03:139868 spdy::SpdySerializedFrame connect2(spdy_util_.ConstructSpdyConnect(
Matt Menke6e879bd2019-03-18 17:26:049869 kAuthCredentials, base::size(kAuthCredentials) / 2, 3,
9870 HttpProxyConnectJob::kH2QuicTunnelPriority,
bncce36dca22015-04-21 22:11:239871 HostPortPair("www.example.org", 443)));
9872 // fetch https://www.example.org/ via HTTP
9873 const char get[] =
9874 "GET / HTTP/1.1\r\n"
9875 "Host: www.example.org\r\n"
9876 "Connection: keep-alive\r\n\r\n";
Ryan Hamilton0239aac2018-05-19 00:03:139877 spdy::SpdySerializedFrame wrapped_get(
Bence Békyd74f4382018-02-20 18:26:199878 spdy_util_.ConstructSpdyDataFrame(3, get, false));
[email protected]0c5fb722012-02-28 11:50:359879
9880 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:419881 CreateMockWrite(req, 0, ASYNC), CreateMockWrite(rst, 2, ASYNC),
9882 CreateMockWrite(connect2, 3), CreateMockWrite(wrapped_get, 5),
[email protected]0c5fb722012-02-28 11:50:359883 };
9884
9885 // The proxy responds to the connect with a 407, using a persistent
9886 // connection.
thestig9d3bb0c2015-01-24 00:49:519887 const char kAuthStatus[] = "407";
[email protected]0c5fb722012-02-28 11:50:359888 const char* const kAuthChallenge[] = {
[email protected]0c5fb722012-02-28 11:50:359889 "proxy-authenticate", "Basic realm=\"MyRealm1\"",
9890 };
Ryan Hamilton0239aac2018-05-19 00:03:139891 spdy::SpdySerializedFrame conn_auth_resp(spdy_util_.ConstructSpdyReplyError(
Avi Drissman4365a4782018-12-28 19:26:249892 kAuthStatus, kAuthChallenge, base::size(kAuthChallenge) / 2, 1));
[email protected]0c5fb722012-02-28 11:50:359893
Ryan Hamilton0239aac2018-05-19 00:03:139894 spdy::SpdySerializedFrame conn_resp(
Raul Tambre94493c652019-03-11 17:18:359895 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
[email protected]0c5fb722012-02-28 11:50:359896 const char resp[] = "HTTP/1.1 200 OK\r\n"
9897 "Content-Length: 5\r\n\r\n";
9898
Ryan Hamilton0239aac2018-05-19 00:03:139899 spdy::SpdySerializedFrame wrapped_get_resp(
Bence Békyd74f4382018-02-20 18:26:199900 spdy_util_.ConstructSpdyDataFrame(3, resp, false));
Ryan Hamilton0239aac2018-05-19 00:03:139901 spdy::SpdySerializedFrame wrapped_body(
Bence Békyd74f4382018-02-20 18:26:199902 spdy_util_.ConstructSpdyDataFrame(3, "hello", false));
[email protected]0c5fb722012-02-28 11:50:359903 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:419904 CreateMockRead(conn_auth_resp, 1, ASYNC),
9905 CreateMockRead(conn_resp, 4, ASYNC),
9906 CreateMockRead(wrapped_get_resp, 6, ASYNC),
9907 CreateMockRead(wrapped_body, 7, ASYNC),
rch8e6c6c42015-05-01 14:05:139908 MockRead(ASYNC, OK, 8), // EOF. May or may not be read.
[email protected]0c5fb722012-02-28 11:50:359909 };
9910
Ryan Sleevib8d7ea02018-05-07 20:01:019911 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:079912 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]0c5fb722012-02-28 11:50:359913 // Negotiate SPDY to the proxy
9914 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:369915 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:079916 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]0c5fb722012-02-28 11:50:359917 // Vanilla SSL to the server
9918 SSLSocketDataProvider server(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:079919 session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
[email protected]0c5fb722012-02-28 11:50:359920
9921 TestCompletionCallback callback1;
9922
bnc87dcefc2017-05-25 12:47:589923 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:199924 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]0c5fb722012-02-28 11:50:359925
9926 int rv = trans->Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:019927 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359928
9929 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:019930 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:469931 TestNetLogEntry::List entries;
[email protected]0c5fb722012-02-28 11:50:359932 log.GetEntries(&entries);
9933 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:009934 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
9935 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:359936 ExpectLogContainsSomewhere(
9937 entries, pos,
mikecirone8b85c432016-09-08 19:11:009938 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
9939 NetLogEventPhase::NONE);
[email protected]0c5fb722012-02-28 11:50:359940
9941 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529942 ASSERT_TRUE(response);
9943 ASSERT_TRUE(response->headers);
[email protected]0c5fb722012-02-28 11:50:359944 EXPECT_EQ(407, response->headers->response_code());
9945 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
Emily Starkf2c9bbd2019-04-09 17:08:589946 EXPECT_TRUE(response->auth_challenge.has_value());
9947 EXPECT_TRUE(CheckBasicSecureProxyAuth(response->auth_challenge));
[email protected]0c5fb722012-02-28 11:50:359948
9949 TestCompletionCallback callback2;
9950
9951 rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
9952 callback2.callback());
robpercival214763f2016-07-01 23:27:019953 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0c5fb722012-02-28 11:50:359954
9955 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:019956 EXPECT_THAT(rv, IsOk());
[email protected]0c5fb722012-02-28 11:50:359957
9958 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:529959 ASSERT_TRUE(response);
[email protected]0c5fb722012-02-28 11:50:359960
9961 EXPECT_TRUE(response->headers->IsKeepAlive());
9962 EXPECT_EQ(200, response->headers->response_code());
9963 EXPECT_EQ(5, response->headers->GetContentLength());
9964 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
9965
9966 // The password prompt info should not be set.
Emily Starkf2c9bbd2019-04-09 17:08:589967 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]0c5fb722012-02-28 11:50:359968
[email protected]029c83b62013-01-24 05:28:209969 LoadTimingInfo load_timing_info;
9970 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
9971 TestLoadTimingNotReusedWithPac(load_timing_info,
9972 CONNECT_TIMING_HAS_SSL_TIMES);
9973
[email protected]0c5fb722012-02-28 11:50:359974 trans.reset();
9975 session->CloseAllConnections();
9976}
9977
[email protected]7c6f7ba2012-04-03 04:09:299978// Test that an explicitly trusted SPDY proxy can push a resource from an
9979// origin that is different from that of its associated resource.
bncd16676a2016-07-20 16:23:019980TEST_F(HttpNetworkTransactionTest, CrossOriginSPDYProxyPush) {
tbansal28e68f82016-02-04 02:56:159981 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:199982 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:159983 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
9984 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]7c6f7ba2012-04-03 04:09:299985 HttpRequestInfo request;
9986 HttpRequestInfo push_request;
Ramin Halavatib5e433e62018-02-07 07:41:109987 request.traffic_annotation =
9988 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299989
[email protected]7c6f7ba2012-04-03 04:09:299990 request.method = "GET";
bncce36dca22015-04-21 22:11:239991 request.url = GURL("http://www.example.org/");
[email protected]7c6f7ba2012-04-03 04:09:299992 push_request.method = "GET";
9993 push_request.url = GURL("http://www.another-origin.com/foo.dat");
Ramin Halavatib5e433e62018-02-07 07:41:109994 push_request.traffic_annotation =
9995 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]7c6f7ba2012-04-03 04:09:299996
tbansal28e68f82016-02-04 02:56:159997 // Configure against https proxy server "myproxy:443".
Lily Houghton8c2f97d2018-01-22 05:06:599998 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:499999 ProxyResolutionService::CreateFixedFromPacResult(
10000 "HTTPS myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110001 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710002 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:5010003
Eric Roman3d8546a2018-09-10 17:00:5210004 session_deps_.proxy_resolution_service->SetProxyDelegate(
10005 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:5010006
danakj1fd259a02016-04-16 03:17:0910007 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7c6f7ba2012-04-03 04:09:2910008
Ryan Hamilton0239aac2018-05-19 00:03:1310009 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510010 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1310011 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:3510012 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
[email protected]7c6f7ba2012-04-03 04:09:2910013
10014 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110015 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:3510016 CreateMockWrite(stream2_priority, 3, ASYNC),
[email protected]7c6f7ba2012-04-03 04:09:2910017 };
10018
Ryan Hamilton0239aac2018-05-19 00:03:1310019 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Raul Tambre94493c652019-03-11 17:18:3510020 nullptr, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
Bence Béky7bf94362018-01-10 13:19:3610021
Ryan Hamilton0239aac2018-05-19 00:03:1310022 spdy::SpdySerializedFrame stream1_reply(
Raul Tambre94493c652019-03-11 17:18:3510023 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]7c6f7ba2012-04-03 04:09:2910024
Ryan Hamilton0239aac2018-05-19 00:03:1310025 spdy::SpdySerializedFrame stream1_body(
10026 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]7c6f7ba2012-04-03 04:09:2910027
Ryan Hamilton0239aac2018-05-19 00:03:1310028 spdy::SpdySerializedFrame stream2_body(
Bence Békyd74f4382018-02-20 18:26:1910029 spdy_util_.ConstructSpdyDataFrame(2, "pushed", true));
[email protected]7c6f7ba2012-04-03 04:09:2910030
10031 MockRead spdy_reads[] = {
Bence Béky7bf94362018-01-10 13:19:3610032 CreateMockRead(stream2_syn, 1, ASYNC),
10033 CreateMockRead(stream1_reply, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:3510034 CreateMockRead(stream1_body, 4, ASYNC),
10035 CreateMockRead(stream2_body, 5, ASYNC),
10036 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
[email protected]7c6f7ba2012-04-03 04:09:2910037 };
10038
Ryan Sleevib8d7ea02018-05-07 20:01:0110039 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710040 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]7c6f7ba2012-04-03 04:09:2910041 // Negotiate SPDY to the proxy
10042 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610043 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710044 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]7c6f7ba2012-04-03 04:09:2910045
bnc87dcefc2017-05-25 12:47:5810046 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910047 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]7c6f7ba2012-04-03 04:09:2910048 TestCompletionCallback callback;
10049 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110050 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:2910051
10052 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110053 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910054 const HttpResponseInfo* response = trans->GetResponseInfo();
10055
bnc87dcefc2017-05-25 12:47:5810056 auto push_trans =
Jeremy Roman0579ed62017-08-29 15:56:1910057 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]90499482013-06-01 00:39:5010058 rv = push_trans->Start(&push_request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110059 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7c6f7ba2012-04-03 04:09:2910060
10061 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110062 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910063 const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
10064
wezca1070932016-05-26 20:30:5210065 ASSERT_TRUE(response);
[email protected]7c6f7ba2012-04-03 04:09:2910066 EXPECT_TRUE(response->headers->IsKeepAlive());
10067
10068 EXPECT_EQ(200, response->headers->response_code());
10069 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10070
10071 std::string response_data;
10072 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110073 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910074 EXPECT_EQ("hello!", response_data);
10075
[email protected]029c83b62013-01-24 05:28:2010076 LoadTimingInfo load_timing_info;
10077 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
10078 TestLoadTimingNotReusedWithPac(load_timing_info,
10079 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10080
[email protected]7c6f7ba2012-04-03 04:09:2910081 // Verify the pushed stream.
wezca1070932016-05-26 20:30:5210082 EXPECT_TRUE(push_response->headers);
[email protected]7c6f7ba2012-04-03 04:09:2910083 EXPECT_EQ(200, push_response->headers->response_code());
10084
10085 rv = ReadTransaction(push_trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110086 EXPECT_THAT(rv, IsOk());
[email protected]7c6f7ba2012-04-03 04:09:2910087 EXPECT_EQ("pushed", response_data);
10088
[email protected]029c83b62013-01-24 05:28:2010089 LoadTimingInfo push_load_timing_info;
10090 EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
10091 TestLoadTimingReusedWithPac(push_load_timing_info);
10092 // The transactions should share a socket ID, despite being for different
10093 // origins.
10094 EXPECT_EQ(load_timing_info.socket_log_id,
10095 push_load_timing_info.socket_log_id);
10096
[email protected]7c6f7ba2012-04-03 04:09:2910097 trans.reset();
10098 push_trans.reset();
10099 session->CloseAllConnections();
10100}
10101
[email protected]8c843192012-04-05 07:15:0010102// Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
bncd16676a2016-07-20 16:23:0110103TEST_F(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510104 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910105 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510106 proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI(
10107 "https://myproxy:443", net::ProxyServer::SCHEME_HTTP));
[email protected]8c843192012-04-05 07:15:0010108 HttpRequestInfo request;
10109
10110 request.method = "GET";
bncce36dca22015-04-21 22:11:2310111 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010112 request.traffic_annotation =
10113 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c843192012-04-05 07:15:0010114
Ramin Halavatica8d5252018-03-12 05:33:4910115 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10116 "https://myproxy:443", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110117 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0710118 session_deps_.net_log = log.bound().net_log();
[email protected]61b4efc2012-04-27 18:12:5010119
10120 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210121 session_deps_.proxy_resolution_service->SetProxyDelegate(
10122 proxy_delegate.get());
[email protected]61b4efc2012-04-27 18:12:5010123
danakj1fd259a02016-04-16 03:17:0910124 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8c843192012-04-05 07:15:0010125
Ryan Hamilton0239aac2018-05-19 00:03:1310126 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510127 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
[email protected]8c843192012-04-05 07:15:0010128
Ryan Hamilton0239aac2018-05-19 00:03:1310129 spdy::SpdySerializedFrame push_rst(
10130 spdy_util_.ConstructSpdyRstStream(2, spdy::ERROR_CODE_REFUSED_STREAM));
[email protected]8c843192012-04-05 07:15:0010131
10132 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110133 CreateMockWrite(stream1_syn, 0, ASYNC), CreateMockWrite(push_rst, 3),
[email protected]8c843192012-04-05 07:15:0010134 };
10135
Ryan Hamilton0239aac2018-05-19 00:03:1310136 spdy::SpdySerializedFrame stream1_reply(
Raul Tambre94493c652019-03-11 17:18:3510137 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
[email protected]8c843192012-04-05 07:15:0010138
Ryan Hamilton0239aac2018-05-19 00:03:1310139 spdy::SpdySerializedFrame stream1_body(
10140 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]8c843192012-04-05 07:15:0010141
Ryan Hamilton0239aac2018-05-19 00:03:1310142 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Raul Tambre94493c652019-03-11 17:18:3510143 nullptr, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
[email protected]8c843192012-04-05 07:15:0010144
10145 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110146 CreateMockRead(stream1_reply, 1, ASYNC),
10147 CreateMockRead(stream2_syn, 2, ASYNC),
10148 CreateMockRead(stream1_body, 4, ASYNC),
mmenkee24011922015-12-17 22:12:5910149 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5), // Force a hang
[email protected]8c843192012-04-05 07:15:0010150 };
10151
Ryan Sleevib8d7ea02018-05-07 20:01:0110152 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0710153 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]8c843192012-04-05 07:15:0010154 // Negotiate SPDY to the proxy
10155 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610156 proxy.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0710157 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
[email protected]8c843192012-04-05 07:15:0010158
bnc87dcefc2017-05-25 12:47:5810159 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910160 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]8c843192012-04-05 07:15:0010161 TestCompletionCallback callback;
10162 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110163 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8c843192012-04-05 07:15:0010164
10165 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110166 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010167 const HttpResponseInfo* response = trans->GetResponseInfo();
10168
wezca1070932016-05-26 20:30:5210169 ASSERT_TRUE(response);
[email protected]8c843192012-04-05 07:15:0010170 EXPECT_TRUE(response->headers->IsKeepAlive());
10171
10172 EXPECT_EQ(200, response->headers->response_code());
10173 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10174
10175 std::string response_data;
10176 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110177 EXPECT_THAT(rv, IsOk());
[email protected]8c843192012-04-05 07:15:0010178 EXPECT_EQ("hello!", response_data);
10179
10180 trans.reset();
10181 session->CloseAllConnections();
10182}
10183
tbansal8ef1d3e2016-02-03 04:05:4210184// Test that an explicitly trusted SPDY proxy can push same-origin HTTPS
10185// resources.
bncd16676a2016-07-20 16:23:0110186TEST_F(HttpNetworkTransactionTest, SameOriginProxyPushCorrectness) {
tbansal28e68f82016-02-04 02:56:1510187 // Configure the proxy delegate to allow cross-origin SPDY pushes.
Jeremy Roman0579ed62017-08-29 15:56:1910188 auto proxy_delegate = std::make_unique<TestProxyDelegate>();
tbansal28e68f82016-02-04 02:56:1510189 proxy_delegate->set_trusted_spdy_proxy(
10190 net::ProxyServer::FromURI("myproxy:70", net::ProxyServer::SCHEME_HTTP));
10191
tbansal8ef1d3e2016-02-03 04:05:4210192 HttpRequestInfo request;
10193
10194 request.method = "GET";
10195 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010196 request.traffic_annotation =
10197 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210198
10199 // Configure against https proxy server "myproxy:70".
Ramin Halavatica8d5252018-03-12 05:33:4910200 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10201 "https://myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
tbansal8ef1d3e2016-02-03 04:05:4210202 BoundTestNetLog log;
10203 session_deps_.net_log = log.bound().net_log();
10204
10205 // Enable cross-origin push.
Eric Roman3d8546a2018-09-10 17:00:5210206 session_deps_.proxy_resolution_service->SetProxyDelegate(
10207 proxy_delegate.get());
tbansal8ef1d3e2016-02-03 04:05:4210208
danakj1fd259a02016-04-16 03:17:0910209 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
tbansal8ef1d3e2016-02-03 04:05:4210210
Ryan Hamilton0239aac2018-05-19 00:03:1310211 spdy::SpdySerializedFrame stream1_syn(
bncb26024382016-06-29 02:39:4510212 spdy_util_.ConstructSpdyGet("http://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1310213 spdy::SpdySerializedFrame stream2_priority(
tombergan5d22c182017-01-11 02:05:3510214 spdy_util_.ConstructSpdyPriority(2, 1, IDLE, true));
tbansal8ef1d3e2016-02-03 04:05:4210215
10216 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4110217 CreateMockWrite(stream1_syn, 0, ASYNC),
tombergan5d22c182017-01-11 02:05:3510218 CreateMockWrite(stream2_priority, 3, ASYNC),
tbansal8ef1d3e2016-02-03 04:05:4210219 };
10220
Ryan Hamilton0239aac2018-05-19 00:03:1310221 spdy::SpdySerializedFrame stream1_reply(
bnc42331402016-07-25 13:36:1510222 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210223
Ryan Hamilton0239aac2018-05-19 00:03:1310224 spdy::SpdySerializedFrame stream2_syn(spdy_util_.ConstructSpdyPush(
Bence Béky096cf052017-08-08 23:55:3310225 nullptr, 0, 2, 1, "http://www.example.org/foo.dat"));
bnc38dcd392016-02-09 23:19:4910226
Ryan Hamilton0239aac2018-05-19 00:03:1310227 spdy::SpdySerializedFrame stream1_body(
10228 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210229
Ryan Hamilton0239aac2018-05-19 00:03:1310230 spdy::SpdySerializedFrame stream2_reply(
bnc42331402016-07-25 13:36:1510231 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
tbansal8ef1d3e2016-02-03 04:05:4210232
Ryan Hamilton0239aac2018-05-19 00:03:1310233 spdy::SpdySerializedFrame stream2_body(
10234 spdy_util_.ConstructSpdyDataFrame(1, true));
tbansal8ef1d3e2016-02-03 04:05:4210235
10236 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4110237 CreateMockRead(stream1_reply, 1, ASYNC),
10238 CreateMockRead(stream2_syn, 2, ASYNC),
tombergan5d22c182017-01-11 02:05:3510239 CreateMockRead(stream1_body, 4, ASYNC),
10240 CreateMockRead(stream2_body, 5, ASYNC),
10241 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 6), // Force a hang
tbansal8ef1d3e2016-02-03 04:05:4210242 };
10243
Ryan Sleevib8d7ea02018-05-07 20:01:0110244 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
tbansal8ef1d3e2016-02-03 04:05:4210245 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
10246 // Negotiate SPDY to the proxy
10247 SSLSocketDataProvider proxy(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3610248 proxy.next_proto = kProtoHTTP2;
tbansal8ef1d3e2016-02-03 04:05:4210249 session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
10250
bnc87dcefc2017-05-25 12:47:5810251 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1910252 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tbansal8ef1d3e2016-02-03 04:05:4210253 TestCompletionCallback callback;
10254 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0110255 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
tbansal8ef1d3e2016-02-03 04:05:4210256
10257 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110258 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210259 const HttpResponseInfo* response = trans->GetResponseInfo();
10260
wezca1070932016-05-26 20:30:5210261 ASSERT_TRUE(response);
tbansal8ef1d3e2016-02-03 04:05:4210262 EXPECT_TRUE(response->headers->IsKeepAlive());
10263
10264 EXPECT_EQ(200, response->headers->response_code());
10265 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
10266
10267 std::string response_data;
10268 rv = ReadTransaction(trans.get(), &response_data);
robpercival214763f2016-07-01 23:27:0110269 EXPECT_THAT(rv, IsOk());
tbansal8ef1d3e2016-02-03 04:05:4210270 EXPECT_EQ("hello!", response_data);
10271
10272 trans.reset();
10273 session->CloseAllConnections();
10274}
10275
[email protected]2df19bb2010-08-25 20:13:4610276// Test HTTPS connections to a site with a bad certificate, going through an
10277// HTTPS proxy
bncd16676a2016-07-20 16:23:0110278TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
Ramin Halavatica8d5252018-03-12 05:33:4910279 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10280 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610281
10282 HttpRequestInfo request;
10283 request.method = "GET";
bncce36dca22015-04-21 22:11:2310284 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010285 request.traffic_annotation =
10286 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2df19bb2010-08-25 20:13:4610287
10288 // Attempt to fetch the URL from a server with a bad cert
10289 MockWrite bad_cert_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710290 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10291 "Host: www.example.org:443\r\n"
10292 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610293 };
10294
10295 MockRead bad_cert_reads[] = {
10296 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610297 MockRead(SYNCHRONOUS, OK)
[email protected]2df19bb2010-08-25 20:13:4610298 };
10299
10300 // Attempt to fetch the URL with a good cert
10301 MockWrite good_data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1710302 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
10303 "Host: www.example.org:443\r\n"
10304 "Proxy-Connection: keep-alive\r\n\r\n"),
10305 MockWrite("GET / HTTP/1.1\r\n"
10306 "Host: www.example.org\r\n"
10307 "Connection: keep-alive\r\n\r\n"),
[email protected]2df19bb2010-08-25 20:13:4610308 };
10309
10310 MockRead good_cert_reads[] = {
10311 MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
10312 MockRead("HTTP/1.0 200 OK\r\n"),
10313 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10314 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610315 MockRead(SYNCHRONOUS, OK),
[email protected]2df19bb2010-08-25 20:13:4610316 };
10317
Ryan Sleevib8d7ea02018-05-07 20:01:0110318 StaticSocketDataProvider ssl_bad_certificate(bad_cert_reads, bad_cert_writes);
10319 StaticSocketDataProvider data(good_cert_reads, good_data_writes);
[email protected]8ddf8322012-02-23 18:08:0610320 SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
10321 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]2df19bb2010-08-25 20:13:4610322
10323 // SSL to the proxy, then CONNECT request, then SSL with bad certificate
[email protected]bb88e1d32013-05-03 23:11:0710324 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10325 session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
10326 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
[email protected]2df19bb2010-08-25 20:13:4610327
10328 // SSL to the proxy, then CONNECT request, then valid SSL certificate
[email protected]bb88e1d32013-05-03 23:11:0710329 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
10330 session_deps_.socket_factory->AddSocketDataProvider(&data);
10331 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2df19bb2010-08-25 20:13:4610332
[email protected]49639fa2011-12-20 23:22:4110333 TestCompletionCallback callback;
[email protected]2df19bb2010-08-25 20:13:4610334
danakj1fd259a02016-04-16 03:17:0910335 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610336 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]2df19bb2010-08-25 20:13:4610337
tfarina42834112016-09-22 13:38:2010338 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110339 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610340
10341 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110342 EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID));
[email protected]2df19bb2010-08-25 20:13:4610343
bnc691fda62016-08-12 00:43:1610344 rv = trans.RestartIgnoringLastError(callback.callback());
robpercival214763f2016-07-01 23:27:0110345 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2df19bb2010-08-25 20:13:4610346
10347 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110348 EXPECT_THAT(rv, IsOk());
[email protected]2df19bb2010-08-25 20:13:4610349
bnc691fda62016-08-12 00:43:1610350 const HttpResponseInfo* response = trans.GetResponseInfo();
[email protected]2df19bb2010-08-25 20:13:4610351
wezca1070932016-05-26 20:30:5210352 ASSERT_TRUE(response);
[email protected]2df19bb2010-08-25 20:13:4610353 EXPECT_EQ(100, response->headers->GetContentLength());
10354}
10355
bncd16676a2016-07-20 16:23:0110356TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
[email protected]1c773ea12009-04-28 19:58:4210357 HttpRequestInfo request;
10358 request.method = "GET";
bncce36dca22015-04-21 22:11:2310359 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310360 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10361 "Chromium Ultra Awesome X Edition");
Ramin Halavatib5e433e62018-02-07 07:41:1010362 request.traffic_annotation =
10363 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210364
danakj1fd259a02016-04-16 03:17:0910365 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610366 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710367
[email protected]1c773ea12009-04-28 19:58:4210368 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310369 MockWrite(
10370 "GET / HTTP/1.1\r\n"
10371 "Host: www.example.org\r\n"
10372 "Connection: keep-alive\r\n"
10373 "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210374 };
10375
10376 // Lastly, the server responds with the actual content.
10377 MockRead data_reads[] = {
10378 MockRead("HTTP/1.0 200 OK\r\n"),
10379 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10380 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610381 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210382 };
10383
Ryan Sleevib8d7ea02018-05-07 20:01:0110384 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710385 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210386
[email protected]49639fa2011-12-20 23:22:4110387 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210388
tfarina42834112016-09-22 13:38:2010389 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110390 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210391
10392 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110393 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210394}
10395
bncd16676a2016-07-20 16:23:0110396TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
Matt Menked732ea42019-03-08 12:05:0010397 // Test user agent values, used both for the request header of the original
10398 // request, and the value returned by the HttpUserAgentSettings. nullptr means
10399 // no request header / no HttpUserAgentSettings object.
10400 const char* kTestUserAgents[] = {nullptr, "", "Foopy"};
[email protected]da81f132010-08-18 23:39:2910401
Matt Menked732ea42019-03-08 12:05:0010402 for (const char* setting_user_agent : kTestUserAgents) {
10403 if (!setting_user_agent) {
10404 session_deps_.http_user_agent_settings.reset();
10405 } else {
10406 session_deps_.http_user_agent_settings =
10407 std::make_unique<StaticHttpUserAgentSettings>(
10408 std::string() /* accept-language */, setting_user_agent);
10409 }
10410 session_deps_.proxy_resolution_service =
10411 ProxyResolutionService::CreateFixed("myproxy:70",
10412 TRAFFIC_ANNOTATION_FOR_TESTS);
10413 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
10414 for (const char* request_user_agent : kTestUserAgents) {
10415 HttpRequestInfo request;
10416 request.method = "GET";
10417 request.url = GURL("https://www.example.org/");
10418 if (request_user_agent) {
10419 request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
10420 request_user_agent);
10421 }
10422 request.traffic_annotation =
10423 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710424
Matt Menked732ea42019-03-08 12:05:0010425 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]da81f132010-08-18 23:39:2910426
Matt Menked732ea42019-03-08 12:05:0010427 std::string expected_request;
10428 if (!setting_user_agent || strlen(setting_user_agent) == 0) {
10429 expected_request =
10430 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10431 "Host: www.example.org:443\r\n"
10432 "Proxy-Connection: keep-alive\r\n\r\n";
10433 } else {
10434 expected_request = base::StringPrintf(
10435 "CONNECT www.example.org:443 HTTP/1.1\r\n"
10436 "Host: www.example.org:443\r\n"
10437 "Proxy-Connection: keep-alive\r\n"
10438 "User-Agent: %s\r\n\r\n",
10439 setting_user_agent);
10440 }
10441 MockWrite data_writes[] = {
10442 MockWrite(expected_request.c_str()),
10443 };
10444 MockRead data_reads[] = {
10445 // Return an error, so the transaction stops here (this test isn't
10446 // interested in the rest).
10447 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
10448 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
10449 MockRead("Proxy-Connection: close\r\n\r\n"),
10450 };
[email protected]da81f132010-08-18 23:39:2910451
Matt Menked732ea42019-03-08 12:05:0010452 StaticSocketDataProvider data(data_reads, data_writes);
10453 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]da81f132010-08-18 23:39:2910454
Matt Menked732ea42019-03-08 12:05:0010455 TestCompletionCallback callback;
[email protected]da81f132010-08-18 23:39:2910456
Matt Menked732ea42019-03-08 12:05:0010457 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
10458 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
10459
10460 rv = callback.WaitForResult();
10461 EXPECT_THAT(rv, IsOk());
10462 }
10463 }
[email protected]da81f132010-08-18 23:39:2910464}
10465
bncd16676a2016-07-20 16:23:0110466TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
[email protected]1c773ea12009-04-28 19:58:4210467 HttpRequestInfo request;
10468 request.method = "GET";
bncce36dca22015-04-21 22:11:2310469 request.url = GURL("http://www.example.org/");
[email protected]c10450102011-06-27 09:06:1610470 request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
10471 "http://the.previous.site.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1010472 request.traffic_annotation =
10473 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210474
danakj1fd259a02016-04-16 03:17:0910475 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610476 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710477
[email protected]1c773ea12009-04-28 19:58:4210478 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310479 MockWrite(
10480 "GET / HTTP/1.1\r\n"
10481 "Host: www.example.org\r\n"
10482 "Connection: keep-alive\r\n"
10483 "Referer: http://the.previous.site.com/\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210484 };
10485
10486 // Lastly, the server responds with the actual content.
10487 MockRead data_reads[] = {
10488 MockRead("HTTP/1.0 200 OK\r\n"),
10489 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10490 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610491 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210492 };
10493
Ryan Sleevib8d7ea02018-05-07 20:01:0110494 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710495 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210496
[email protected]49639fa2011-12-20 23:22:4110497 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210498
tfarina42834112016-09-22 13:38:2010499 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110500 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210501
10502 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110503 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210504}
10505
bncd16676a2016-07-20 16:23:0110506TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210507 HttpRequestInfo request;
10508 request.method = "POST";
bncce36dca22015-04-21 22:11:2310509 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010510 request.traffic_annotation =
10511 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210512
danakj1fd259a02016-04-16 03:17:0910513 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610514 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710515
[email protected]1c773ea12009-04-28 19:58:4210516 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310517 MockWrite(
10518 "POST / HTTP/1.1\r\n"
10519 "Host: www.example.org\r\n"
10520 "Connection: keep-alive\r\n"
10521 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210522 };
10523
10524 // Lastly, the server responds with the actual content.
10525 MockRead data_reads[] = {
10526 MockRead("HTTP/1.0 200 OK\r\n"),
10527 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10528 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610529 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210530 };
10531
Ryan Sleevib8d7ea02018-05-07 20:01:0110532 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710533 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210534
[email protected]49639fa2011-12-20 23:22:4110535 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210536
tfarina42834112016-09-22 13:38:2010537 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110538 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210539
10540 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110541 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210542}
10543
bncd16676a2016-07-20 16:23:0110544TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210545 HttpRequestInfo request;
10546 request.method = "PUT";
bncce36dca22015-04-21 22:11:2310547 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010548 request.traffic_annotation =
10549 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210550
danakj1fd259a02016-04-16 03:17:0910551 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610552 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710553
[email protected]1c773ea12009-04-28 19:58:4210554 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310555 MockWrite(
10556 "PUT / HTTP/1.1\r\n"
10557 "Host: www.example.org\r\n"
10558 "Connection: keep-alive\r\n"
10559 "Content-Length: 0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210560 };
10561
10562 // Lastly, the server responds with the actual content.
10563 MockRead data_reads[] = {
10564 MockRead("HTTP/1.0 200 OK\r\n"),
10565 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10566 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610567 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210568 };
10569
Ryan Sleevib8d7ea02018-05-07 20:01:0110570 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710571 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210572
[email protected]49639fa2011-12-20 23:22:4110573 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210574
tfarina42834112016-09-22 13:38:2010575 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110576 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210577
10578 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110579 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210580}
10581
bncd16676a2016-07-20 16:23:0110582TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
[email protected]1c773ea12009-04-28 19:58:4210583 HttpRequestInfo request;
10584 request.method = "HEAD";
bncce36dca22015-04-21 22:11:2310585 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010586 request.traffic_annotation =
10587 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210588
danakj1fd259a02016-04-16 03:17:0910589 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610590 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710591
[email protected]1c773ea12009-04-28 19:58:4210592 MockWrite data_writes[] = {
csharrisonf473dd192015-08-18 13:54:1310593 MockWrite("HEAD / HTTP/1.1\r\n"
10594 "Host: www.example.org\r\n"
10595 "Connection: keep-alive\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210596 };
10597
10598 // Lastly, the server responds with the actual content.
10599 MockRead data_reads[] = {
10600 MockRead("HTTP/1.0 200 OK\r\n"),
10601 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10602 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610603 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210604 };
10605
Ryan Sleevib8d7ea02018-05-07 20:01:0110606 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710607 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210608
[email protected]49639fa2011-12-20 23:22:4110609 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210610
tfarina42834112016-09-22 13:38:2010611 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110612 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210613
10614 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110615 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210616}
10617
bncd16676a2016-07-20 16:23:0110618TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
[email protected]1c773ea12009-04-28 19:58:4210619 HttpRequestInfo request;
10620 request.method = "GET";
bncce36dca22015-04-21 22:11:2310621 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210622 request.load_flags = LOAD_BYPASS_CACHE;
Ramin Halavatib5e433e62018-02-07 07:41:1010623 request.traffic_annotation =
10624 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210625
danakj1fd259a02016-04-16 03:17:0910626 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610627 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710628
[email protected]1c773ea12009-04-28 19:58:4210629 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310630 MockWrite(
10631 "GET / HTTP/1.1\r\n"
10632 "Host: www.example.org\r\n"
10633 "Connection: keep-alive\r\n"
10634 "Pragma: no-cache\r\n"
10635 "Cache-Control: no-cache\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210636 };
10637
10638 // Lastly, the server responds with the actual content.
10639 MockRead data_reads[] = {
10640 MockRead("HTTP/1.0 200 OK\r\n"),
10641 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10642 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610643 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210644 };
10645
Ryan Sleevib8d7ea02018-05-07 20:01:0110646 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710647 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210648
[email protected]49639fa2011-12-20 23:22:4110649 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210650
tfarina42834112016-09-22 13:38:2010651 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110652 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210653
10654 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110655 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210656}
10657
bncd16676a2016-07-20 16:23:0110658TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlValidateCache) {
[email protected]1c773ea12009-04-28 19:58:4210659 HttpRequestInfo request;
10660 request.method = "GET";
bncce36dca22015-04-21 22:11:2310661 request.url = GURL("http://www.example.org/");
[email protected]1c773ea12009-04-28 19:58:4210662 request.load_flags = LOAD_VALIDATE_CACHE;
Ramin Halavatib5e433e62018-02-07 07:41:1010663 request.traffic_annotation =
10664 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210665
danakj1fd259a02016-04-16 03:17:0910666 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610667 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710668
[email protected]1c773ea12009-04-28 19:58:4210669 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310670 MockWrite(
10671 "GET / HTTP/1.1\r\n"
10672 "Host: www.example.org\r\n"
10673 "Connection: keep-alive\r\n"
10674 "Cache-Control: max-age=0\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210675 };
10676
10677 // Lastly, the server responds with the actual content.
10678 MockRead data_reads[] = {
10679 MockRead("HTTP/1.0 200 OK\r\n"),
10680 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10681 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610682 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210683 };
10684
Ryan Sleevib8d7ea02018-05-07 20:01:0110685 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710686 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210687
[email protected]49639fa2011-12-20 23:22:4110688 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210689
tfarina42834112016-09-22 13:38:2010690 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110691 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210692
10693 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110694 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210695}
10696
bncd16676a2016-07-20 16:23:0110697TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
[email protected]1c773ea12009-04-28 19:58:4210698 HttpRequestInfo request;
10699 request.method = "GET";
bncce36dca22015-04-21 22:11:2310700 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310701 request.extra_headers.SetHeader("FooHeader", "Bar");
Ramin Halavatib5e433e62018-02-07 07:41:1010702 request.traffic_annotation =
10703 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]1c773ea12009-04-28 19:58:4210704
danakj1fd259a02016-04-16 03:17:0910705 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610706 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710707
[email protected]1c773ea12009-04-28 19:58:4210708 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310709 MockWrite(
10710 "GET / HTTP/1.1\r\n"
10711 "Host: www.example.org\r\n"
10712 "Connection: keep-alive\r\n"
10713 "FooHeader: Bar\r\n\r\n"),
[email protected]1c773ea12009-04-28 19:58:4210714 };
10715
10716 // Lastly, the server responds with the actual content.
10717 MockRead data_reads[] = {
10718 MockRead("HTTP/1.0 200 OK\r\n"),
10719 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10720 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610721 MockRead(SYNCHRONOUS, OK),
[email protected]1c773ea12009-04-28 19:58:4210722 };
10723
Ryan Sleevib8d7ea02018-05-07 20:01:0110724 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710725 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]1c773ea12009-04-28 19:58:4210726
[email protected]49639fa2011-12-20 23:22:4110727 TestCompletionCallback callback;
[email protected]1c773ea12009-04-28 19:58:4210728
tfarina42834112016-09-22 13:38:2010729 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110730 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]1c773ea12009-04-28 19:58:4210731
10732 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110733 EXPECT_THAT(rv, IsOk());
[email protected]1c773ea12009-04-28 19:58:4210734}
10735
bncd16676a2016-07-20 16:23:0110736TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
[email protected]270c6412010-03-29 22:02:4710737 HttpRequestInfo request;
10738 request.method = "GET";
bncce36dca22015-04-21 22:11:2310739 request.url = GURL("http://www.example.org/");
[email protected]8c76ae22010-04-20 22:15:4310740 request.extra_headers.SetHeader("referer", "www.foo.com");
10741 request.extra_headers.SetHeader("hEllo", "Kitty");
10742 request.extra_headers.SetHeader("FoO", "bar");
Ramin Halavatib5e433e62018-02-07 07:41:1010743 request.traffic_annotation =
10744 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]270c6412010-03-29 22:02:4710745
danakj1fd259a02016-04-16 03:17:0910746 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610747 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2710748
[email protected]270c6412010-03-29 22:02:4710749 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310750 MockWrite(
10751 "GET / HTTP/1.1\r\n"
10752 "Host: www.example.org\r\n"
10753 "Connection: keep-alive\r\n"
10754 "referer: www.foo.com\r\n"
10755 "hEllo: Kitty\r\n"
10756 "FoO: bar\r\n\r\n"),
[email protected]270c6412010-03-29 22:02:4710757 };
10758
10759 // Lastly, the server responds with the actual content.
10760 MockRead data_reads[] = {
10761 MockRead("HTTP/1.0 200 OK\r\n"),
10762 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
10763 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0610764 MockRead(SYNCHRONOUS, OK),
[email protected]270c6412010-03-29 22:02:4710765 };
10766
Ryan Sleevib8d7ea02018-05-07 20:01:0110767 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710768 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]270c6412010-03-29 22:02:4710769
[email protected]49639fa2011-12-20 23:22:4110770 TestCompletionCallback callback;
[email protected]270c6412010-03-29 22:02:4710771
tfarina42834112016-09-22 13:38:2010772 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110773 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]270c6412010-03-29 22:02:4710774
10775 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110776 EXPECT_THAT(rv, IsOk());
[email protected]270c6412010-03-29 22:02:4710777}
10778
bncd16676a2016-07-20 16:23:0110779TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710780 HttpRequestInfo request;
10781 request.method = "GET";
bncce36dca22015-04-21 22:11:2310782 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010783 request.traffic_annotation =
10784 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710785
Lily Houghton8c2f97d2018-01-22 05:06:5910786 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910787 ProxyResolutionService::CreateFixedFromPacResult(
10788 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110789 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710790 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210791
danakj1fd259a02016-04-16 03:17:0910792 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610793 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210794
[email protected]3cd17242009-06-23 02:59:0210795 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
10796 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10797
10798 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410799 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
10800 MockWrite("GET / HTTP/1.1\r\n"
10801 "Host: www.example.org\r\n"
10802 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210803
10804 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410805 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
10806 MockRead("HTTP/1.0 200 OK\r\n"),
10807 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10808 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0210809
Ryan Sleevib8d7ea02018-05-07 20:01:0110810 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710811 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0210812
[email protected]49639fa2011-12-20 23:22:4110813 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0210814
tfarina42834112016-09-22 13:38:2010815 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110816 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0210817
10818 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110819 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210820
bnc691fda62016-08-12 00:43:1610821 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210822 ASSERT_TRUE(response);
[email protected]3cd17242009-06-23 02:59:0210823
tbansal2ecbbc72016-10-06 17:15:4710824 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]029c83b62013-01-24 05:28:2010825 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610826 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010827 TestLoadTimingNotReusedWithPac(load_timing_info,
10828 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10829
[email protected]3cd17242009-06-23 02:59:0210830 std::string response_text;
bnc691fda62016-08-12 00:43:1610831 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110832 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0210833 EXPECT_EQ("Payload", response_text);
10834}
10835
bncd16676a2016-07-20 16:23:0110836TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710837 HttpRequestInfo request;
10838 request.method = "GET";
bncce36dca22015-04-21 22:11:2310839 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010840 request.traffic_annotation =
10841 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710842
Lily Houghton8c2f97d2018-01-22 05:06:5910843 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910844 ProxyResolutionService::CreateFixedFromPacResult(
10845 "SOCKS myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110846 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710847 session_deps_.net_log = &net_log;
[email protected]3cd17242009-06-23 02:59:0210848
danakj1fd259a02016-04-16 03:17:0910849 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610850 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]3cd17242009-06-23 02:59:0210851
[email protected]3cd17242009-06-23 02:59:0210852 unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
10853 unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10854
10855 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2310856 MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
Avi Drissman4365a4782018-12-28 19:26:2410857 base::size(write_buffer)),
10858 MockWrite("GET / HTTP/1.1\r\n"
10859 "Host: www.example.org\r\n"
10860 "Connection: keep-alive\r\n\r\n")};
[email protected]3cd17242009-06-23 02:59:0210861
10862 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410863 MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
10864 base::size(read_buffer)),
10865 MockRead("HTTP/1.0 200 OK\r\n"),
10866 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10867 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3510868
Ryan Sleevib8d7ea02018-05-07 20:01:0110869 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710870 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3510871
[email protected]8ddf8322012-02-23 18:08:0610872 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0710873 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]e0c27be2009-07-15 13:09:3510874
[email protected]49639fa2011-12-20 23:22:4110875 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3510876
tfarina42834112016-09-22 13:38:2010877 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110878 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3510879
10880 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110881 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510882
[email protected]029c83b62013-01-24 05:28:2010883 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610884 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010885 TestLoadTimingNotReusedWithPac(load_timing_info,
10886 CONNECT_TIMING_HAS_SSL_TIMES);
10887
bnc691fda62016-08-12 00:43:1610888 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210889 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4710890 EXPECT_EQ(ProxyServer::SCHEME_SOCKS4, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3510891
10892 std::string response_text;
bnc691fda62016-08-12 00:43:1610893 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110894 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3510895 EXPECT_EQ("Payload", response_text);
10896}
10897
bncd16676a2016-07-20 16:23:0110898TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
[email protected]029c83b62013-01-24 05:28:2010899 HttpRequestInfo request;
10900 request.method = "GET";
bncce36dca22015-04-21 22:11:2310901 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010902 request.traffic_annotation =
10903 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]029c83b62013-01-24 05:28:2010904
Ramin Halavatica8d5252018-03-12 05:33:4910905 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
10906 "socks4://myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110907 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710908 session_deps_.net_log = &net_log;
[email protected]029c83b62013-01-24 05:28:2010909
danakj1fd259a02016-04-16 03:17:0910910 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610911 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]029c83b62013-01-24 05:28:2010912
10913 char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
10914 char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
10915
10916 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410917 MockWrite(ASYNC, write_buffer, base::size(write_buffer)),
10918 MockWrite("GET / HTTP/1.1\r\n"
10919 "Host: www.example.org\r\n"
10920 "Connection: keep-alive\r\n\r\n")};
[email protected]029c83b62013-01-24 05:28:2010921
10922 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410923 MockRead(ASYNC, read_buffer, base::size(read_buffer)),
10924 MockRead("HTTP/1.0 200 OK\r\n"),
10925 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10926 MockRead("Payload"), MockRead(SYNCHRONOUS, OK)};
[email protected]029c83b62013-01-24 05:28:2010927
Ryan Sleevib8d7ea02018-05-07 20:01:0110928 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710929 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]029c83b62013-01-24 05:28:2010930
10931 TestCompletionCallback callback;
10932
tfarina42834112016-09-22 13:38:2010933 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0110934 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]029c83b62013-01-24 05:28:2010935
10936 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0110937 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2010938
bnc691fda62016-08-12 00:43:1610939 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5210940 ASSERT_TRUE(response);
[email protected]029c83b62013-01-24 05:28:2010941
10942 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1610943 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2010944 TestLoadTimingNotReused(load_timing_info,
10945 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
10946
10947 std::string response_text;
bnc691fda62016-08-12 00:43:1610948 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0110949 EXPECT_THAT(rv, IsOk());
[email protected]029c83b62013-01-24 05:28:2010950 EXPECT_EQ("Payload", response_text);
10951}
10952
bncd16676a2016-07-20 16:23:0110953TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2710954 HttpRequestInfo request;
10955 request.method = "GET";
bncce36dca22015-04-21 22:11:2310956 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1010957 request.traffic_annotation =
10958 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2710959
Lily Houghton8c2f97d2018-01-22 05:06:5910960 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4910961 ProxyResolutionService::CreateFixedFromPacResult(
10962 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5110963 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0710964 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3510965
danakj1fd259a02016-04-16 03:17:0910966 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1610967 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3510968
[email protected]e0c27be2009-07-15 13:09:3510969 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
10970 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3710971 const char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2310972 0x05, // Version
10973 0x01, // Command (CONNECT)
10974 0x00, // Reserved.
10975 0x03, // Address type (DOMAINNAME).
10976 0x0F, // Length of domain (15)
10977 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
10978 '.', 'o', 'r', 'g', 0x00, 0x50, // 16-bit port (80)
[email protected]f209dba2009-12-18 00:24:3710979 };
[email protected]e0c27be2009-07-15 13:09:3510980 const char kSOCKS5OkResponse[] =
10981 { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
10982
10983 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2410984 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
10985 MockWrite(ASYNC, kSOCKS5OkRequest, base::size(kSOCKS5OkRequest)),
10986 MockWrite("GET / HTTP/1.1\r\n"
10987 "Host: www.example.org\r\n"
10988 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3510989
10990 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2410991 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
10992 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
10993 MockRead("HTTP/1.0 200 OK\r\n"),
10994 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
10995 MockRead("Payload"),
10996 MockRead(SYNCHRONOUS, OK)};
[email protected]e0c27be2009-07-15 13:09:3510997
Ryan Sleevib8d7ea02018-05-07 20:01:0110998 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0710999 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]e0c27be2009-07-15 13:09:3511000
[email protected]49639fa2011-12-20 23:22:4111001 TestCompletionCallback callback;
[email protected]e0c27be2009-07-15 13:09:3511002
tfarina42834112016-09-22 13:38:2011003 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111004 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]e0c27be2009-07-15 13:09:3511005
11006 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111007 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3511008
bnc691fda62016-08-12 00:43:1611009 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211010 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4711011 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]e0c27be2009-07-15 13:09:3511012
[email protected]029c83b62013-01-24 05:28:2011013 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1611014 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2011015 TestLoadTimingNotReusedWithPac(load_timing_info,
11016 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
11017
[email protected]e0c27be2009-07-15 13:09:3511018 std::string response_text;
bnc691fda62016-08-12 00:43:1611019 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111020 EXPECT_THAT(rv, IsOk());
[email protected]e0c27be2009-07-15 13:09:3511021 EXPECT_EQ("Payload", response_text);
11022}
11023
bncd16676a2016-07-20 16:23:0111024TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
[email protected]cb9bf6ca2011-01-28 13:15:2711025 HttpRequestInfo request;
11026 request.method = "GET";
bncce36dca22015-04-21 22:11:2311027 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011028 request.traffic_annotation =
11029 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711030
Lily Houghton8c2f97d2018-01-22 05:06:5911031 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911032 ProxyResolutionService::CreateFixedFromPacResult(
11033 "SOCKS5 myproxy:1080", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5111034 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0711035 session_deps_.net_log = &net_log;
[email protected]e0c27be2009-07-15 13:09:3511036
danakj1fd259a02016-04-16 03:17:0911037 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611038 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]e0c27be2009-07-15 13:09:3511039
[email protected]e0c27be2009-07-15 13:09:3511040 const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
11041 const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
[email protected]f209dba2009-12-18 00:24:3711042 const unsigned char kSOCKS5OkRequest[] = {
bncce36dca22015-04-21 22:11:2311043 0x05, // Version
11044 0x01, // Command (CONNECT)
11045 0x00, // Reserved.
11046 0x03, // Address type (DOMAINNAME).
11047 0x0F, // Length of domain (15)
11048 'w', 'w', 'w', '.', 'e', 'x', 'a', 'm', 'p', 'l', 'e', // Domain string
11049 '.', 'o', 'r', 'g', 0x01, 0xBB, // 16-bit port (443)
[email protected]f209dba2009-12-18 00:24:3711050 };
11051
[email protected]e0c27be2009-07-15 13:09:3511052 const char kSOCKS5OkResponse[] =
11053 { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
11054
11055 MockWrite data_writes[] = {
Avi Drissman4365a4782018-12-28 19:26:2411056 MockWrite(ASYNC, kSOCKS5GreetRequest, base::size(kSOCKS5GreetRequest)),
bncce36dca22015-04-21 22:11:2311057 MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
Avi Drissman4365a4782018-12-28 19:26:2411058 base::size(kSOCKS5OkRequest)),
11059 MockWrite("GET / HTTP/1.1\r\n"
11060 "Host: www.example.org\r\n"
11061 "Connection: keep-alive\r\n\r\n")};
[email protected]e0c27be2009-07-15 13:09:3511062
11063 MockRead data_reads[] = {
Avi Drissman4365a4782018-12-28 19:26:2411064 MockRead(ASYNC, kSOCKS5GreetResponse, base::size(kSOCKS5GreetResponse)),
11065 MockRead(ASYNC, kSOCKS5OkResponse, base::size(kSOCKS5OkResponse)),
11066 MockRead("HTTP/1.0 200 OK\r\n"),
11067 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
11068 MockRead("Payload"),
11069 MockRead(SYNCHRONOUS, OK)};
[email protected]3cd17242009-06-23 02:59:0211070
Ryan Sleevib8d7ea02018-05-07 20:01:0111071 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0711072 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]3cd17242009-06-23 02:59:0211073
[email protected]8ddf8322012-02-23 18:08:0611074 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0711075 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]3cd17242009-06-23 02:59:0211076
[email protected]49639fa2011-12-20 23:22:4111077 TestCompletionCallback callback;
[email protected]3cd17242009-06-23 02:59:0211078
tfarina42834112016-09-22 13:38:2011079 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111080 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3cd17242009-06-23 02:59:0211081
11082 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111083 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0211084
bnc691fda62016-08-12 00:43:1611085 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211086 ASSERT_TRUE(response);
tbansal2ecbbc72016-10-06 17:15:4711087 EXPECT_EQ(ProxyServer::SCHEME_SOCKS5, response->proxy_server.scheme());
[email protected]3cd17242009-06-23 02:59:0211088
[email protected]029c83b62013-01-24 05:28:2011089 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1611090 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2011091 TestLoadTimingNotReusedWithPac(load_timing_info,
11092 CONNECT_TIMING_HAS_SSL_TIMES);
11093
[email protected]3cd17242009-06-23 02:59:0211094 std::string response_text;
bnc691fda62016-08-12 00:43:1611095 rv = ReadTransaction(&trans, &response_text);
robpercival214763f2016-07-01 23:27:0111096 EXPECT_THAT(rv, IsOk());
[email protected]3cd17242009-06-23 02:59:0211097 EXPECT_EQ("Payload", response_text);
11098}
11099
[email protected]448d4ca52012-03-04 04:12:2311100namespace {
11101
Matt Menkef6edce752019-03-19 17:21:5611102// Tests that for connection endpoints the group ids are correctly set.
[email protected]2d731a32010-04-29 01:04:0611103
Matt Menkef6edce752019-03-19 17:21:5611104struct GroupIdTest {
[email protected]2d731a32010-04-29 01:04:0611105 std::string proxy_server;
11106 std::string url;
Matt Menkef6edce752019-03-19 17:21:5611107 ClientSocketPool::GroupId expected_group_id;
[email protected]e60e47a2010-07-14 03:37:1811108 bool ssl;
[email protected]2d731a32010-04-29 01:04:0611109};
11110
Matt Menkef6edce752019-03-19 17:21:5611111std::unique_ptr<HttpNetworkSession> SetupSessionForGroupIdTests(
[email protected]bb88e1d32013-05-03 23:11:0711112 SpdySessionDependencies* session_deps_) {
danakj1fd259a02016-04-16 03:17:0911113 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps_));
[email protected]2d731a32010-04-29 01:04:0611114
bnc525e175a2016-06-20 12:36:4011115 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5311116 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2111117 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnc7dc7e1b42015-07-28 14:43:1211118 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2111119 http_server_properties->SetHttp2AlternativeService(
bncaa60ff402016-06-22 19:12:4211120 url::SchemeHostPort("https", "host.with.alternate", 443),
zhongyi3d4a55e72016-04-22 20:36:4611121 alternative_service, expiration);
[email protected]2d731a32010-04-29 01:04:0611122
11123 return session;
11124}
11125
Matt Menkef6edce752019-03-19 17:21:5611126int GroupIdTransactionHelper(const std::string& url,
11127 HttpNetworkSession* session) {
[email protected]2d731a32010-04-29 01:04:0611128 HttpRequestInfo request;
11129 request.method = "GET";
11130 request.url = GURL(url);
Ramin Halavatib5e433e62018-02-07 07:41:1011131 request.traffic_annotation =
11132 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d731a32010-04-29 01:04:0611133
bnc691fda62016-08-12 00:43:1611134 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
[email protected]cb9bf6ca2011-01-28 13:15:2711135
[email protected]49639fa2011-12-20 23:22:4111136 TestCompletionCallback callback;
[email protected]2d731a32010-04-29 01:04:0611137
11138 // We do not complete this request, the dtor will clean the transaction up.
tfarina42834112016-09-22 13:38:2011139 return trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]2d731a32010-04-29 01:04:0611140}
11141
[email protected]448d4ca52012-03-04 04:12:2311142} // namespace
11143
Matt Menkef6edce752019-03-19 17:21:5611144TEST_F(HttpNetworkTransactionTest, GroupIdForDirectConnections) {
11145 const GroupIdTest tests[] = {
bncce36dca22015-04-21 22:11:2311146 {
Matt Menkef6edce752019-03-19 17:21:5611147 "", // unused
11148 "http://www.example.org/direct",
11149 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11150 ClientSocketPool::SocketType::kHttp,
Matt Menkebdf777802019-04-22 19:38:5911151 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menkef6edce752019-03-19 17:21:5611152 false,
bncce36dca22015-04-21 22:11:2311153 },
11154 {
Matt Menkef6edce752019-03-19 17:21:5611155 "", // unused
11156 "http://[2001:1418:13:1::25]/direct",
11157 ClientSocketPool::GroupId(HostPortPair("2001:1418:13:1::25", 80),
11158 ClientSocketPool::SocketType::kHttp,
Matt Menkebdf777802019-04-22 19:38:5911159 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menkef6edce752019-03-19 17:21:5611160 false,
bncce36dca22015-04-21 22:11:2311161 },
[email protected]04e5be32009-06-26 20:00:3111162
bncce36dca22015-04-21 22:11:2311163 // SSL Tests
11164 {
Matt Menkef6edce752019-03-19 17:21:5611165 "", // unused
11166 "https://www.example.org/direct_ssl",
11167 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11168 ClientSocketPool::SocketType::kSsl,
Matt Menkebdf777802019-04-22 19:38:5911169 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menkef6edce752019-03-19 17:21:5611170 true,
bncce36dca22015-04-21 22:11:2311171 },
11172 {
Matt Menkef6edce752019-03-19 17:21:5611173 "", // unused
11174 "https://[2001:1418:13:1::25]/direct",
11175 ClientSocketPool::GroupId(HostPortPair("2001:1418:13:1::25", 443),
11176 ClientSocketPool::SocketType::kSsl,
Matt Menkebdf777802019-04-22 19:38:5911177 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menkef6edce752019-03-19 17:21:5611178 true,
bncce36dca22015-04-21 22:11:2311179 },
11180 {
Matt Menkef6edce752019-03-19 17:21:5611181 "", // unused
11182 "https://host.with.alternate/direct",
11183 ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
11184 ClientSocketPool::SocketType::kSsl,
Matt Menkebdf777802019-04-22 19:38:5911185 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menkef6edce752019-03-19 17:21:5611186 true,
bncce36dca22015-04-21 22:11:2311187 },
[email protected]2d731a32010-04-29 01:04:0611188 };
[email protected]2ff8b312010-04-26 22:20:5411189
Avi Drissman4365a4782018-12-28 19:26:2411190 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911191 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911192 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11193 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911194 std::unique_ptr<HttpNetworkSession> session(
Matt Menkef6edce752019-03-19 17:21:5611195 SetupSessionForGroupIdTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611196
mmenkee65e7af2015-10-13 17:16:4211197 HttpNetworkSessionPeer peer(session.get());
Matt Menkef6edce752019-03-19 17:21:5611198 CaptureGroupIdTransportSocketPool* transport_conn_pool =
Matt Menked6fd2a52019-03-20 06:14:3611199 new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
Jeremy Roman0579ed62017-08-29 15:56:1911200 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4011201 mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
11202 base::WrapUnique(transport_conn_pool));
dchengc7eeda422015-12-26 03:56:4811203 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611204
11205 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef6edce752019-03-19 17:21:5611206 GroupIdTransactionHelper(tests[i].url, session.get()));
11207 EXPECT_EQ(tests[i].expected_group_id,
11208 transport_conn_pool->last_group_id_received());
Matt Menke9d5e2c92019-02-05 01:42:2311209 EXPECT_TRUE(transport_conn_pool->socket_requested());
[email protected]2d731a32010-04-29 01:04:0611210 }
[email protected]2d731a32010-04-29 01:04:0611211}
11212
Matt Menkef6edce752019-03-19 17:21:5611213TEST_F(HttpNetworkTransactionTest, GroupIdForHTTPProxyConnections) {
11214 const GroupIdTest tests[] = {
bncce36dca22015-04-21 22:11:2311215 {
Matt Menke4802de62019-03-08 22:47:5011216 "http_proxy",
11217 "http://www.example.org/http_proxy_normal",
Matt Menkef6edce752019-03-19 17:21:5611218 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11219 ClientSocketPool::SocketType::kHttp,
Matt Menkebdf777802019-04-22 19:38:5911220 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menke4802de62019-03-08 22:47:5011221 false,
bncce36dca22015-04-21 22:11:2311222 },
[email protected]2d731a32010-04-29 01:04:0611223
bncce36dca22015-04-21 22:11:2311224 // SSL Tests
11225 {
Matt Menke4802de62019-03-08 22:47:5011226 "http_proxy",
11227 "https://www.example.org/http_connect_ssl",
Matt Menkef6edce752019-03-19 17:21:5611228 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11229 ClientSocketPool::SocketType::kSsl,
Matt Menkebdf777802019-04-22 19:38:5911230 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menke4802de62019-03-08 22:47:5011231 true,
bncce36dca22015-04-21 22:11:2311232 },
[email protected]af3490e2010-10-16 21:02:2911233
bncce36dca22015-04-21 22:11:2311234 {
Matt Menke4802de62019-03-08 22:47:5011235 "http_proxy",
11236 "https://host.with.alternate/direct",
Matt Menkef6edce752019-03-19 17:21:5611237 ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
11238 ClientSocketPool::SocketType::kSsl,
Matt Menkebdf777802019-04-22 19:38:5911239 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menke4802de62019-03-08 22:47:5011240 true,
bncce36dca22015-04-21 22:11:2311241 },
[email protected]45499252013-01-23 17:12:5611242
bncce36dca22015-04-21 22:11:2311243 {
Matt Menke4802de62019-03-08 22:47:5011244 "http_proxy",
11245 "ftp://ftp.google.com/http_proxy_normal",
Matt Menkef6edce752019-03-19 17:21:5611246 ClientSocketPool::GroupId(HostPortPair("ftp.google.com", 21),
11247 ClientSocketPool::SocketType::kFtp,
Matt Menkebdf777802019-04-22 19:38:5911248 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menke4802de62019-03-08 22:47:5011249 false,
bncce36dca22015-04-21 22:11:2311250 },
[email protected]2d731a32010-04-29 01:04:0611251 };
11252
Avi Drissman4365a4782018-12-28 19:26:2411253 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911254 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911255 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11256 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911257 std::unique_ptr<HttpNetworkSession> session(
Matt Menkef6edce752019-03-19 17:21:5611258 SetupSessionForGroupIdTests(&session_deps_));
[email protected]2d731a32010-04-29 01:04:0611259
mmenkee65e7af2015-10-13 17:16:4211260 HttpNetworkSessionPeer peer(session.get());
[email protected]2d731a32010-04-29 01:04:0611261
Matt Menkee8648fa2019-01-17 16:47:0711262 ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
11263 HostPortPair("http_proxy", 80));
Matt Menkef6edce752019-03-19 17:21:5611264 CaptureGroupIdTransportSocketPool* http_proxy_pool =
Matt Menked6fd2a52019-03-20 06:14:3611265 new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
Jeremy Roman0579ed62017-08-29 15:56:1911266 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4011267 mock_pool_manager->SetSocketPool(proxy_server,
11268 base::WrapUnique(http_proxy_pool));
dchengc7eeda422015-12-26 03:56:4811269 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]2d731a32010-04-29 01:04:0611270
11271 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef6edce752019-03-19 17:21:5611272 GroupIdTransactionHelper(tests[i].url, session.get()));
11273 EXPECT_EQ(tests[i].expected_group_id,
11274 http_proxy_pool->last_group_id_received());
[email protected]2d731a32010-04-29 01:04:0611275 }
[email protected]2d731a32010-04-29 01:04:0611276}
11277
Matt Menkef6edce752019-03-19 17:21:5611278TEST_F(HttpNetworkTransactionTest, GroupIdForSOCKSConnections) {
11279 const GroupIdTest tests[] = {
bncce36dca22015-04-21 22:11:2311280 {
Matt Menke4802de62019-03-08 22:47:5011281 "socks4://socks_proxy:1080",
11282 "http://www.example.org/socks4_direct",
Matt Menkef6edce752019-03-19 17:21:5611283 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11284 ClientSocketPool::SocketType::kHttp,
Matt Menkebdf777802019-04-22 19:38:5911285 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menke4802de62019-03-08 22:47:5011286 false,
bncce36dca22015-04-21 22:11:2311287 },
11288 {
Matt Menke4802de62019-03-08 22:47:5011289 "socks5://socks_proxy:1080",
11290 "http://www.example.org/socks5_direct",
Matt Menkef6edce752019-03-19 17:21:5611291 ClientSocketPool::GroupId(HostPortPair("www.example.org", 80),
11292 ClientSocketPool::SocketType::kHttp,
Matt Menkebdf777802019-04-22 19:38:5911293 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menke4802de62019-03-08 22:47:5011294 false,
bncce36dca22015-04-21 22:11:2311295 },
[email protected]2d731a32010-04-29 01:04:0611296
bncce36dca22015-04-21 22:11:2311297 // SSL Tests
11298 {
Matt Menke4802de62019-03-08 22:47:5011299 "socks4://socks_proxy:1080",
11300 "https://www.example.org/socks4_ssl",
Matt Menkef6edce752019-03-19 17:21:5611301 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11302 ClientSocketPool::SocketType::kSsl,
Matt Menkebdf777802019-04-22 19:38:5911303 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menke4802de62019-03-08 22:47:5011304 true,
bncce36dca22015-04-21 22:11:2311305 },
11306 {
Matt Menke4802de62019-03-08 22:47:5011307 "socks5://socks_proxy:1080",
11308 "https://www.example.org/socks5_ssl",
Matt Menkef6edce752019-03-19 17:21:5611309 ClientSocketPool::GroupId(HostPortPair("www.example.org", 443),
11310 ClientSocketPool::SocketType::kSsl,
Matt Menkebdf777802019-04-22 19:38:5911311 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menke4802de62019-03-08 22:47:5011312 true,
bncce36dca22015-04-21 22:11:2311313 },
[email protected]af3490e2010-10-16 21:02:2911314
bncce36dca22015-04-21 22:11:2311315 {
Matt Menke4802de62019-03-08 22:47:5011316 "socks4://socks_proxy:1080",
11317 "https://host.with.alternate/direct",
Matt Menkef6edce752019-03-19 17:21:5611318 ClientSocketPool::GroupId(HostPortPair("host.with.alternate", 443),
11319 ClientSocketPool::SocketType::kSsl,
Matt Menkebdf777802019-04-22 19:38:5911320 PrivacyMode::PRIVACY_MODE_DISABLED),
Matt Menke4802de62019-03-08 22:47:5011321 true,
bncce36dca22015-04-21 22:11:2311322 },
[email protected]04e5be32009-06-26 20:00:3111323 };
11324
Avi Drissman4365a4782018-12-28 19:26:2411325 for (size_t i = 0; i < base::size(tests); ++i) {
Lily Houghton8c2f97d2018-01-22 05:06:5911326 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4911327 ProxyResolutionService::CreateFixed(tests[i].proxy_server,
11328 TRAFFIC_ANNOTATION_FOR_TESTS);
danakj1fd259a02016-04-16 03:17:0911329 std::unique_ptr<HttpNetworkSession> session(
Matt Menkef6edce752019-03-19 17:21:5611330 SetupSessionForGroupIdTests(&session_deps_));
[email protected]8b114dd72011-03-25 05:33:0211331
mmenkee65e7af2015-10-13 17:16:4211332 HttpNetworkSessionPeer peer(session.get());
[email protected]04e5be32009-06-26 20:00:3111333
Matt Menkee8648fa2019-01-17 16:47:0711334 ProxyServer proxy_server(
11335 ProxyServer::FromURI(tests[i].proxy_server, ProxyServer::SCHEME_HTTP));
11336 ASSERT_TRUE(proxy_server.is_valid());
Matt Menkef6edce752019-03-19 17:21:5611337 CaptureGroupIdTransportSocketPool* socks_conn_pool =
Matt Menked6fd2a52019-03-20 06:14:3611338 new CaptureGroupIdTransportSocketPool(&dummy_connect_job_params_);
Jeremy Roman0579ed62017-08-29 15:56:1911339 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4011340 mock_pool_manager->SetSocketPool(proxy_server,
11341 base::WrapUnique(socks_conn_pool));
dchengc7eeda422015-12-26 03:56:4811342 peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]04e5be32009-06-26 20:00:3111343
bnc691fda62016-08-12 00:43:1611344 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]04e5be32009-06-26 20:00:3111345
[email protected]2d731a32010-04-29 01:04:0611346 EXPECT_EQ(ERR_IO_PENDING,
Matt Menkef6edce752019-03-19 17:21:5611347 GroupIdTransactionHelper(tests[i].url, session.get()));
11348 EXPECT_EQ(tests[i].expected_group_id,
11349 socks_conn_pool->last_group_id_received());
[email protected]04e5be32009-06-26 20:00:3111350 }
11351}
11352
bncd16676a2016-07-20 16:23:0111353TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
[email protected]cb9bf6ca2011-01-28 13:15:2711354 HttpRequestInfo request;
11355 request.method = "GET";
bncce36dca22015-04-21 22:11:2311356 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011357 request.traffic_annotation =
11358 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2711359
Ramin Halavatica8d5252018-03-12 05:33:4911360 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11361 "myproxy:70;foobar:80", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]b59ff372009-07-15 22:04:3211362
[email protected]69719062010-01-05 20:09:2111363 // This simulates failure resolving all hostnames; that means we will fail
11364 // connecting to both proxies (myproxy:70 and foobar:80).
[email protected]bb88e1d32013-05-03 23:11:0711365 session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
[email protected]b59ff372009-07-15 22:04:3211366
danakj1fd259a02016-04-16 03:17:0911367 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611368 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]9172a982009-06-06 00:30:2511369
[email protected]49639fa2011-12-20 23:22:4111370 TestCompletionCallback callback;
[email protected]9172a982009-06-06 00:30:2511371
tfarina42834112016-09-22 13:38:2011372 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111373 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9172a982009-06-06 00:30:2511374
[email protected]9172a982009-06-06 00:30:2511375 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111376 EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
[email protected]9172a982009-06-06 00:30:2511377}
11378
[email protected]0877e3d2009-10-17 22:29:5711379// Make sure we can handle an error when writing the request.
bncd16676a2016-07-20 16:23:0111380TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
[email protected]0877e3d2009-10-17 22:29:5711381 HttpRequestInfo request;
11382 request.method = "GET";
11383 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1011384 request.traffic_annotation =
11385 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711386
11387 MockWrite write_failure[] = {
[email protected]8ddf8322012-02-23 18:08:0611388 MockWrite(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5711389 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111390 StaticSocketDataProvider data(base::span<MockRead>(), write_failure);
[email protected]bb88e1d32013-05-03 23:11:0711391 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0911392 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711393
[email protected]49639fa2011-12-20 23:22:4111394 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711395
bnc691fda62016-08-12 00:43:1611396 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711397
tfarina42834112016-09-22 13:38:2011398 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111399 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711400
11401 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111402 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
ttuttled9dbc652015-09-29 20:00:5911403
11404 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1611405 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5911406 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5711407}
11408
zmo9528c9f42015-08-04 22:12:0811409// Check that a connection closed after the start of the headers finishes ok.
bncd16676a2016-07-20 16:23:0111410TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
[email protected]0877e3d2009-10-17 22:29:5711411 HttpRequestInfo request;
11412 request.method = "GET";
11413 request.url = GURL("http://www.foo.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1011414 request.traffic_annotation =
11415 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711416
11417 MockRead data_reads[] = {
11418 MockRead("HTTP/1."),
[email protected]8ddf8322012-02-23 18:08:0611419 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5711420 };
11421
Ryan Sleevib8d7ea02018-05-07 20:01:0111422 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711423 session_deps_.socket_factory->AddSocketDataProvider(&data);
danakj1fd259a02016-04-16 03:17:0911424 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711425
[email protected]49639fa2011-12-20 23:22:4111426 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711427
bnc691fda62016-08-12 00:43:1611428 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711429
tfarina42834112016-09-22 13:38:2011430 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111431 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711432
11433 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111434 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0811435
bnc691fda62016-08-12 00:43:1611436 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211437 ASSERT_TRUE(response);
zmo9528c9f42015-08-04 22:12:0811438
wezca1070932016-05-26 20:30:5211439 EXPECT_TRUE(response->headers);
zmo9528c9f42015-08-04 22:12:0811440 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11441
11442 std::string response_data;
bnc691fda62016-08-12 00:43:1611443 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0111444 EXPECT_THAT(rv, IsOk());
zmo9528c9f42015-08-04 22:12:0811445 EXPECT_EQ("", response_data);
ttuttled9dbc652015-09-29 20:00:5911446
11447 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1611448 EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5911449 EXPECT_LT(0u, endpoint.address().size());
[email protected]0877e3d2009-10-17 22:29:5711450}
11451
11452// Make sure that a dropped connection while draining the body for auth
11453// restart does the right thing.
bncd16676a2016-07-20 16:23:0111454TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
[email protected]0877e3d2009-10-17 22:29:5711455 HttpRequestInfo request;
11456 request.method = "GET";
bncce36dca22015-04-21 22:11:2311457 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011458 request.traffic_annotation =
11459 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711460
11461 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311462 MockWrite(
11463 "GET / HTTP/1.1\r\n"
11464 "Host: www.example.org\r\n"
11465 "Connection: keep-alive\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5711466 };
11467
11468 MockRead data_reads1[] = {
11469 MockRead("HTTP/1.1 401 Unauthorized\r\n"),
11470 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
11471 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11472 MockRead("Content-Length: 14\r\n\r\n"),
11473 MockRead("Unauth"),
[email protected]8ddf8322012-02-23 18:08:0611474 MockRead(ASYNC, ERR_CONNECTION_RESET),
[email protected]0877e3d2009-10-17 22:29:5711475 };
11476
Ryan Sleevib8d7ea02018-05-07 20:01:0111477 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0711478 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]0877e3d2009-10-17 22:29:5711479
bnc691fda62016-08-12 00:43:1611480 // After calling trans.RestartWithAuth(), this is the request we should
[email protected]0877e3d2009-10-17 22:29:5711481 // be issuing -- the final header line contains the credentials.
11482 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2311483 MockWrite(
11484 "GET / HTTP/1.1\r\n"
11485 "Host: www.example.org\r\n"
11486 "Connection: keep-alive\r\n"
11487 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
[email protected]0877e3d2009-10-17 22:29:5711488 };
11489
11490 // Lastly, the server responds with the actual content.
11491 MockRead data_reads2[] = {
11492 MockRead("HTTP/1.1 200 OK\r\n"),
11493 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
11494 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611495 MockRead(SYNCHRONOUS, OK),
[email protected]0877e3d2009-10-17 22:29:5711496 };
11497
Ryan Sleevib8d7ea02018-05-07 20:01:0111498 StaticSocketDataProvider data2(data_reads2, data_writes2);
[email protected]bb88e1d32013-05-03 23:11:0711499 session_deps_.socket_factory->AddSocketDataProvider(&data2);
danakj1fd259a02016-04-16 03:17:0911500 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]0877e3d2009-10-17 22:29:5711501
[email protected]49639fa2011-12-20 23:22:4111502 TestCompletionCallback callback1;
[email protected]0877e3d2009-10-17 22:29:5711503
bnc691fda62016-08-12 00:43:1611504 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011505
tfarina42834112016-09-22 13:38:2011506 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111507 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711508
11509 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111510 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5711511
bnc691fda62016-08-12 00:43:1611512 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211513 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5811514 EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge));
[email protected]0877e3d2009-10-17 22:29:5711515
[email protected]49639fa2011-12-20 23:22:4111516 TestCompletionCallback callback2;
[email protected]0877e3d2009-10-17 22:29:5711517
bnc691fda62016-08-12 00:43:1611518 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
robpercival214763f2016-07-01 23:27:0111519 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711520
11521 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0111522 EXPECT_THAT(rv, IsOk());
[email protected]0877e3d2009-10-17 22:29:5711523
bnc691fda62016-08-12 00:43:1611524 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211525 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5811526 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]0877e3d2009-10-17 22:29:5711527 EXPECT_EQ(100, response->headers->GetContentLength());
11528}
11529
11530// Test HTTPS connections going through a proxy that sends extra data.
bncd16676a2016-07-20 16:23:0111531TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
Ramin Halavatica8d5252018-03-12 05:33:4911532 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
11533 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711534
11535 HttpRequestInfo request;
11536 request.method = "GET";
bncce36dca22015-04-21 22:11:2311537 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011538 request.traffic_annotation =
11539 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]0877e3d2009-10-17 22:29:5711540
11541 MockRead proxy_reads[] = {
11542 MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
[email protected]8ddf8322012-02-23 18:08:0611543 MockRead(SYNCHRONOUS, OK)
[email protected]0877e3d2009-10-17 22:29:5711544 };
11545
Ryan Sleevib8d7ea02018-05-07 20:01:0111546 StaticSocketDataProvider data(proxy_reads, base::span<MockWrite>());
[email protected]8ddf8322012-02-23 18:08:0611547 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]0877e3d2009-10-17 22:29:5711548
[email protected]bb88e1d32013-05-03 23:11:0711549 session_deps_.socket_factory->AddSocketDataProvider(&data);
11550 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]0877e3d2009-10-17 22:29:5711551
[email protected]49639fa2011-12-20 23:22:4111552 TestCompletionCallback callback;
[email protected]0877e3d2009-10-17 22:29:5711553
[email protected]bb88e1d32013-05-03 23:11:0711554 session_deps_.socket_factory->ResetNextMockIndexes();
[email protected]0877e3d2009-10-17 22:29:5711555
danakj1fd259a02016-04-16 03:17:0911556 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611557 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0877e3d2009-10-17 22:29:5711558
tfarina42834112016-09-22 13:38:2011559 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111560 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]0877e3d2009-10-17 22:29:5711561
11562 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111563 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
[email protected]0877e3d2009-10-17 22:29:5711564}
11565
bncd16676a2016-07-20 16:23:0111566TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
[email protected]9492e4a2010-02-24 00:58:4611567 HttpRequestInfo request;
11568 request.method = "GET";
bncce36dca22015-04-21 22:11:2311569 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011570 request.traffic_annotation =
11571 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]9492e4a2010-02-24 00:58:4611572
danakj1fd259a02016-04-16 03:17:0911573 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611574 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2711575
[email protected]e22e1362009-11-23 21:31:1211576 MockRead data_reads[] = {
11577 MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0611578 MockRead(SYNCHRONOUS, OK),
[email protected]e22e1362009-11-23 21:31:1211579 };
[email protected]9492e4a2010-02-24 00:58:4611580
Ryan Sleevib8d7ea02018-05-07 20:01:0111581 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711582 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]9492e4a2010-02-24 00:58:4611583
[email protected]49639fa2011-12-20 23:22:4111584 TestCompletionCallback callback;
[email protected]9492e4a2010-02-24 00:58:4611585
tfarina42834112016-09-22 13:38:2011586 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111587 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]9492e4a2010-02-24 00:58:4611588
robpercival214763f2016-07-01 23:27:0111589 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]9492e4a2010-02-24 00:58:4611590
bnc691fda62016-08-12 00:43:1611591 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211592 ASSERT_TRUE(response);
[email protected]9492e4a2010-02-24 00:58:4611593
wezca1070932016-05-26 20:30:5211594 EXPECT_TRUE(response->headers);
[email protected]9492e4a2010-02-24 00:58:4611595 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
11596
11597 std::string response_data;
bnc691fda62016-08-12 00:43:1611598 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0111599 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
[email protected]e22e1362009-11-23 21:31:1211600}
11601
bncd16676a2016-07-20 16:23:0111602TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
[email protected]6cdfd7f2013-02-08 20:40:1511603 base::FilePath temp_file_path;
[email protected]03d9afc02013-12-03 17:55:5211604 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
avibf0746c2015-12-09 19:53:1411605 const uint64_t kFakeSize = 100000; // file is actually blank
[email protected]d98961652012-09-11 20:27:2111606 UploadFileElementReader::ScopedOverridingContentLengthForTests
11607 overriding_content_length(kFakeSize);
[email protected]95d88ffe2010-02-04 21:25:3311608
danakj1fd259a02016-04-16 03:17:0911609 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1911610 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1411611 base::ThreadTaskRunnerHandle::Get().get(), temp_file_path, 0,
ricea2deef682016-09-09 08:04:0711612 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2211613 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2711614
11615 HttpRequestInfo request;
11616 request.method = "POST";
bncce36dca22015-04-21 22:11:2311617 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2711618 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1011619 request.traffic_annotation =
11620 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2711621
danakj1fd259a02016-04-16 03:17:0911622 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611623 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]95d88ffe2010-02-04 21:25:3311624
11625 MockRead data_reads[] = {
11626 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
11627 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0611628 MockRead(SYNCHRONOUS, OK),
[email protected]95d88ffe2010-02-04 21:25:3311629 };
Ryan Sleevib8d7ea02018-05-07 20:01:0111630 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0711631 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]95d88ffe2010-02-04 21:25:3311632
[email protected]49639fa2011-12-20 23:22:4111633 TestCompletionCallback callback;
[email protected]95d88ffe2010-02-04 21:25:3311634
tfarina42834112016-09-22 13:38:2011635 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111636 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]95d88ffe2010-02-04 21:25:3311637
11638 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111639 EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED));
[email protected]95d88ffe2010-02-04 21:25:3311640
bnc691fda62016-08-12 00:43:1611641 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211642 ASSERT_TRUE(response);
[email protected]95d88ffe2010-02-04 21:25:3311643
maksim.sisove869bf52016-06-23 17:11:5211644 EXPECT_FALSE(response->headers);
[email protected]95d88ffe2010-02-04 21:25:3311645
[email protected]dd3aa792013-07-16 19:10:2311646 base::DeleteFile(temp_file_path, false);
[email protected]95d88ffe2010-02-04 21:25:3311647}
11648
bncd16676a2016-07-20 16:23:0111649TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
[email protected]6cdfd7f2013-02-08 20:40:1511650 base::FilePath temp_file;
[email protected]03d9afc02013-12-03 17:55:5211651 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
[email protected]6624b4622010-03-29 19:58:3611652 std::string temp_file_content("Unreadable file.");
lazyboy8df84fc2017-04-12 02:12:4811653 ASSERT_EQ(static_cast<int>(temp_file_content.length()),
11654 base::WriteFile(temp_file, temp_file_content.c_str(),
11655 temp_file_content.length()));
[email protected]92be8eb2014-08-07 22:57:1111656 ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
[email protected]6624b4622010-03-29 19:58:3611657
danakj1fd259a02016-04-16 03:17:0911658 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
Jeremy Roman0579ed62017-08-29 15:56:1911659 element_readers.push_back(std::make_unique<UploadFileElementReader>(
avibf0746c2015-12-09 19:53:1411660 base::ThreadTaskRunnerHandle::Get().get(), temp_file, 0,
ricea2deef682016-09-09 08:04:0711661 std::numeric_limits<uint64_t>::max(), base::Time()));
olli.raula6df48b2a2015-11-26 07:40:2211662 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]329b68b2012-11-14 17:54:2711663
11664 HttpRequestInfo request;
11665 request.method = "POST";
bncce36dca22015-04-21 22:11:2311666 request.url = GURL("http://www.example.org/upload");
[email protected]329b68b2012-11-14 17:54:2711667 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1011668 request.traffic_annotation =
11669 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]329b68b2012-11-14 17:54:2711670
[email protected]999dd8c2013-11-12 06:45:5411671 // If we try to upload an unreadable file, the transaction should fail.
danakj1fd259a02016-04-16 03:17:0911672 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611673 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]6624b4622010-03-29 19:58:3611674
Ryan Sleevib8d7ea02018-05-07 20:01:0111675 StaticSocketDataProvider data;
[email protected]bb88e1d32013-05-03 23:11:0711676 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]6624b4622010-03-29 19:58:3611677
[email protected]49639fa2011-12-20 23:22:4111678 TestCompletionCallback callback;
[email protected]6624b4622010-03-29 19:58:3611679
tfarina42834112016-09-22 13:38:2011680 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111681 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]6624b4622010-03-29 19:58:3611682
11683 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0111684 EXPECT_THAT(rv, IsError(ERR_ACCESS_DENIED));
[email protected]6624b4622010-03-29 19:58:3611685
[email protected]dd3aa792013-07-16 19:10:2311686 base::DeleteFile(temp_file, false);
[email protected]6624b4622010-03-29 19:58:3611687}
11688
bncd16676a2016-07-20 16:23:0111689TEST_F(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
[email protected]02cad5d2013-10-02 08:14:0311690 class FakeUploadElementReader : public UploadElementReader {
11691 public:
Chris Watkins7a41d3552017-12-01 02:13:2711692 FakeUploadElementReader() = default;
11693 ~FakeUploadElementReader() override = default;
[email protected]02cad5d2013-10-02 08:14:0311694
Matt Menkecc1d3a902018-02-05 18:27:3311695 CompletionOnceCallback TakeCallback() { return std::move(callback_); }
[email protected]02cad5d2013-10-02 08:14:0311696
11697 // UploadElementReader overrides:
Matt Menkecc1d3a902018-02-05 18:27:3311698 int Init(CompletionOnceCallback callback) override {
11699 callback_ = std::move(callback);
[email protected]02cad5d2013-10-02 08:14:0311700 return ERR_IO_PENDING;
11701 }
avibf0746c2015-12-09 19:53:1411702 uint64_t GetContentLength() const override { return 0; }
11703 uint64_t BytesRemaining() const override { return 0; }
dchengb03027d2014-10-21 12:00:2011704 int Read(IOBuffer* buf,
11705 int buf_length,
Matt Menkecc1d3a902018-02-05 18:27:3311706 CompletionOnceCallback callback) override {
[email protected]02cad5d2013-10-02 08:14:0311707 return ERR_FAILED;
11708 }
11709
11710 private:
Matt Menkecc1d3a902018-02-05 18:27:3311711 CompletionOnceCallback callback_;
[email protected]02cad5d2013-10-02 08:14:0311712 };
11713
11714 FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
danakj1fd259a02016-04-16 03:17:0911715 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
11716 element_readers.push_back(base::WrapUnique(fake_reader));
olli.raula6df48b2a2015-11-26 07:40:2211717 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02cad5d2013-10-02 08:14:0311718
11719 HttpRequestInfo request;
11720 request.method = "POST";
bncce36dca22015-04-21 22:11:2311721 request.url = GURL("http://www.example.org/upload");
[email protected]02cad5d2013-10-02 08:14:0311722 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1011723 request.traffic_annotation =
11724 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02cad5d2013-10-02 08:14:0311725
danakj1fd259a02016-04-16 03:17:0911726 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5811727 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1911728 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]02cad5d2013-10-02 08:14:0311729
11730 StaticSocketDataProvider data;
11731 session_deps_.socket_factory->AddSocketDataProvider(&data);
11732
11733 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2011734 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111735 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
fdoray92e35a72016-06-10 15:54:5511736 base::RunLoop().RunUntilIdle();
[email protected]02cad5d2013-10-02 08:14:0311737
11738 // Transaction is pending on request body initialization.
Matt Menkecc1d3a902018-02-05 18:27:3311739 CompletionOnceCallback init_callback = fake_reader->TakeCallback();
11740 ASSERT_FALSE(init_callback.is_null());
[email protected]02cad5d2013-10-02 08:14:0311741
11742 // Return Init()'s result after the transaction gets destroyed.
11743 trans.reset();
Matt Menkecc1d3a902018-02-05 18:27:3311744 std::move(init_callback).Run(OK); // Should not crash.
[email protected]02cad5d2013-10-02 08:14:0311745}
11746
[email protected]aeefc9e82010-02-19 16:18:2711747// Tests that changes to Auth realms are treated like auth rejections.
bncd16676a2016-07-20 16:23:0111748TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
[email protected]aeefc9e82010-02-19 16:18:2711749 HttpRequestInfo request;
11750 request.method = "GET";
bncce36dca22015-04-21 22:11:2311751 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011752 request.traffic_annotation =
11753 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]aeefc9e82010-02-19 16:18:2711754
11755 // First transaction will request a resource and receive a Basic challenge
11756 // with realm="first_realm".
11757 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2311758 MockWrite(
11759 "GET / HTTP/1.1\r\n"
11760 "Host: www.example.org\r\n"
11761 "Connection: keep-alive\r\n"
11762 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711763 };
11764 MockRead data_reads1[] = {
11765 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11766 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11767 "\r\n"),
11768 };
11769
bnc691fda62016-08-12 00:43:1611770 // After calling trans.RestartWithAuth(), provide an Authentication header
[email protected]aeefc9e82010-02-19 16:18:2711771 // for first_realm. The server will reject and provide a challenge with
11772 // second_realm.
11773 MockWrite data_writes2[] = {
bncce36dca22015-04-21 22:11:2311774 MockWrite(
11775 "GET / HTTP/1.1\r\n"
11776 "Host: www.example.org\r\n"
11777 "Connection: keep-alive\r\n"
11778 "Authorization: Basic Zmlyc3Q6YmF6\r\n"
11779 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711780 };
11781 MockRead data_reads2[] = {
11782 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11783 "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
11784 "\r\n"),
11785 };
11786
11787 // This again fails, and goes back to first_realm. Make sure that the
11788 // entry is removed from cache.
11789 MockWrite data_writes3[] = {
bncce36dca22015-04-21 22:11:2311790 MockWrite(
11791 "GET / HTTP/1.1\r\n"
11792 "Host: www.example.org\r\n"
11793 "Connection: keep-alive\r\n"
11794 "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
11795 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711796 };
11797 MockRead data_reads3[] = {
11798 MockRead("HTTP/1.1 401 Unauthorized\r\n"
11799 "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
11800 "\r\n"),
11801 };
11802
11803 // Try one last time (with the correct password) and get the resource.
11804 MockWrite data_writes4[] = {
bncce36dca22015-04-21 22:11:2311805 MockWrite(
11806 "GET / HTTP/1.1\r\n"
11807 "Host: www.example.org\r\n"
11808 "Connection: keep-alive\r\n"
11809 "Authorization: Basic Zmlyc3Q6YmFy\r\n"
11810 "\r\n"),
[email protected]aeefc9e82010-02-19 16:18:2711811 };
11812 MockRead data_reads4[] = {
11813 MockRead("HTTP/1.1 200 OK\r\n"
11814 "Content-Type: text/html; charset=iso-8859-1\r\n"
[email protected]0b0bf032010-09-21 18:08:5011815 "Content-Length: 5\r\n"
11816 "\r\n"
11817 "hello"),
[email protected]aeefc9e82010-02-19 16:18:2711818 };
11819
Ryan Sleevib8d7ea02018-05-07 20:01:0111820 StaticSocketDataProvider data1(data_reads1, data_writes1);
11821 StaticSocketDataProvider data2(data_reads2, data_writes2);
11822 StaticSocketDataProvider data3(data_reads3, data_writes3);
11823 StaticSocketDataProvider data4(data_reads4, data_writes4);
[email protected]bb88e1d32013-05-03 23:11:0711824 session_deps_.socket_factory->AddSocketDataProvider(&data1);
11825 session_deps_.socket_factory->AddSocketDataProvider(&data2);
11826 session_deps_.socket_factory->AddSocketDataProvider(&data3);
11827 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]aeefc9e82010-02-19 16:18:2711828
[email protected]49639fa2011-12-20 23:22:4111829 TestCompletionCallback callback1;
[email protected]aeefc9e82010-02-19 16:18:2711830
danakj1fd259a02016-04-16 03:17:0911831 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611832 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5011833
[email protected]aeefc9e82010-02-19 16:18:2711834 // Issue the first request with Authorize headers. There should be a
11835 // password prompt for first_realm waiting to be filled in after the
11836 // transaction completes.
tfarina42834112016-09-22 13:38:2011837 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111838 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711839 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0111840 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611841 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211842 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5811843 base::Optional<AuthChallengeInfo> challenge = response->auth_challenge;
wezca1070932016-05-26 20:30:5211844 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411845 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311846 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411847 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911848 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711849
11850 // Issue the second request with an incorrect password. There should be a
11851 // password prompt for second_realm waiting to be filled in after the
11852 // transaction completes.
[email protected]49639fa2011-12-20 23:22:4111853 TestCompletionCallback callback2;
bnc691fda62016-08-12 00:43:1611854 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz),
11855 callback2.callback());
robpercival214763f2016-07-01 23:27:0111856 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711857 rv = callback2.WaitForResult();
robpercival214763f2016-07-01 23:27:0111858 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611859 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211860 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5811861 challenge = response->auth_challenge;
wezca1070932016-05-26 20:30:5211862 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411863 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311864 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411865 EXPECT_EQ("second_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911866 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711867
11868 // Issue the third request with another incorrect password. There should be
11869 // a password prompt for first_realm waiting to be filled in. If the password
11870 // prompt is not present, it indicates that the HttpAuthCacheEntry for
11871 // first_realm was not correctly removed.
[email protected]49639fa2011-12-20 23:22:4111872 TestCompletionCallback callback3;
bnc691fda62016-08-12 00:43:1611873 rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou),
11874 callback3.callback());
robpercival214763f2016-07-01 23:27:0111875 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711876 rv = callback3.WaitForResult();
robpercival214763f2016-07-01 23:27:0111877 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611878 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211879 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5811880 challenge = response->auth_challenge;
wezca1070932016-05-26 20:30:5211881 ASSERT_TRUE(challenge);
[email protected]79cb5c12011-09-12 13:12:0411882 EXPECT_FALSE(challenge->is_proxy);
asanka098c0092016-06-16 20:18:4311883 EXPECT_EQ("http://www.example.org", challenge->challenger.Serialize());
[email protected]79cb5c12011-09-12 13:12:0411884 EXPECT_EQ("first_realm", challenge->realm);
aberentbba302d2015-12-03 10:20:1911885 EXPECT_EQ(kBasicAuthScheme, challenge->scheme);
[email protected]aeefc9e82010-02-19 16:18:2711886
11887 // Issue the fourth request with the correct password and username.
[email protected]49639fa2011-12-20 23:22:4111888 TestCompletionCallback callback4;
bnc691fda62016-08-12 00:43:1611889 rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar),
11890 callback4.callback());
robpercival214763f2016-07-01 23:27:0111891 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]aeefc9e82010-02-19 16:18:2711892 rv = callback4.WaitForResult();
robpercival214763f2016-07-01 23:27:0111893 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1611894 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211895 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5811896 EXPECT_FALSE(response->auth_challenge.has_value());
[email protected]aeefc9e82010-02-19 16:18:2711897}
11898
Bence Béky230ac612017-08-30 19:17:0811899// Regression test for https://crbug.com/754395.
11900TEST_F(HttpNetworkTransactionTest, IgnoreAltSvcWithInvalidCert) {
11901 MockRead data_reads[] = {
11902 MockRead("HTTP/1.1 200 OK\r\n"),
11903 MockRead(kAlternativeServiceHttpHeader),
11904 MockRead("\r\n"),
11905 MockRead("hello world"),
11906 MockRead(SYNCHRONOUS, OK),
11907 };
11908
11909 HttpRequestInfo request;
11910 request.method = "GET";
11911 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011912 request.traffic_annotation =
11913 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Béky230ac612017-08-30 19:17:0811914
Ryan Sleevib8d7ea02018-05-07 20:01:0111915 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
Bence Béky230ac612017-08-30 19:17:0811916 session_deps_.socket_factory->AddSocketDataProvider(&data);
11917
11918 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911919 ssl.ssl_info.cert =
11920 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11921 ASSERT_TRUE(ssl.ssl_info.cert);
11922 ssl.ssl_info.cert_status = CERT_STATUS_COMMON_NAME_INVALID;
Bence Béky230ac612017-08-30 19:17:0811923 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11924
11925 TestCompletionCallback callback;
11926
11927 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11928 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
11929
11930 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
11931 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
11932
11933 url::SchemeHostPort test_server(request.url);
11934 HttpServerProperties* http_server_properties =
11935 session->http_server_properties();
11936 EXPECT_TRUE(
11937 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11938
11939 EXPECT_THAT(callback.WaitForResult(), IsOk());
11940
11941 const HttpResponseInfo* response = trans.GetResponseInfo();
11942 ASSERT_TRUE(response);
11943 ASSERT_TRUE(response->headers);
11944 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
11945 EXPECT_FALSE(response->was_fetched_via_spdy);
11946 EXPECT_FALSE(response->was_alpn_negotiated);
11947
11948 std::string response_data;
11949 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
11950 EXPECT_EQ("hello world", response_data);
11951
11952 EXPECT_TRUE(
11953 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
11954}
11955
bncd16676a2016-07-20 16:23:0111956TEST_F(HttpNetworkTransactionTest, HonorAlternativeServiceHeader) {
bncc958faa2015-07-31 18:14:5211957 MockRead data_reads[] = {
11958 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4311959 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5211960 MockRead("\r\n"),
11961 MockRead("hello world"),
11962 MockRead(SYNCHRONOUS, OK),
11963 };
11964
11965 HttpRequestInfo request;
11966 request.method = "GET";
bncb26024382016-06-29 02:39:4511967 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1011968 request.traffic_annotation =
11969 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5211970
Ryan Sleevib8d7ea02018-05-07 20:01:0111971 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5211972 session_deps_.socket_factory->AddSocketDataProvider(&data);
11973
bncb26024382016-06-29 02:39:4511974 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4911975 ssl.ssl_info.cert =
11976 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
11977 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4511978 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11979
bncc958faa2015-07-31 18:14:5211980 TestCompletionCallback callback;
11981
danakj1fd259a02016-04-16 03:17:0911982 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1611983 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5211984
tfarina42834112016-09-22 13:38:2011985 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0111986 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5211987
bncb26024382016-06-29 02:39:4511988 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4011989 HttpServerProperties* http_server_properties =
11990 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3411991 EXPECT_TRUE(
11992 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5211993
robpercival214763f2016-07-01 23:27:0111994 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5211995
bnc691fda62016-08-12 00:43:1611996 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5211997 ASSERT_TRUE(response);
11998 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5211999 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12000 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212001 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5212002
12003 std::string response_data;
bnc691fda62016-08-12 00:43:1612004 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5212005 EXPECT_EQ("hello world", response_data);
12006
zhongyic4de03032017-05-19 04:07:3412007 AlternativeServiceInfoVector alternative_service_info_vector =
12008 http_server_properties->GetAlternativeServiceInfos(test_server);
12009 ASSERT_EQ(1u, alternative_service_info_vector.size());
12010 AlternativeService alternative_service(kProtoHTTP2, "mail.example.org", 443);
12011 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412012 alternative_service_info_vector[0].alternative_service());
bncc958faa2015-07-31 18:14:5212013}
12014
bnce3dd56f2016-06-01 10:37:1112015// Regression test for https://crbug.com/615497.
bncd16676a2016-07-20 16:23:0112016TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1112017 DoNotParseAlternativeServiceHeaderOnInsecureRequest) {
bnce3dd56f2016-06-01 10:37:1112018 MockRead data_reads[] = {
12019 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312020 MockRead(kAlternativeServiceHttpHeader),
bnce3dd56f2016-06-01 10:37:1112021 MockRead("\r\n"),
12022 MockRead("hello world"),
12023 MockRead(SYNCHRONOUS, OK),
12024 };
12025
12026 HttpRequestInfo request;
12027 request.method = "GET";
12028 request.url = GURL("http://www.example.org/");
12029 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012030 request.traffic_annotation =
12031 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1112032
Ryan Sleevib8d7ea02018-05-07 20:01:0112033 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1112034 session_deps_.socket_factory->AddSocketDataProvider(&data);
12035
12036 TestCompletionCallback callback;
12037
12038 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612039 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1112040
12041 url::SchemeHostPort test_server(request.url);
bnc525e175a2016-06-20 12:36:4012042 HttpServerProperties* http_server_properties =
12043 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412044 EXPECT_TRUE(
12045 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1112046
tfarina42834112016-09-22 13:38:2012047 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112048 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12049 EXPECT_THAT(callback.WaitForResult(), IsOk());
bnce3dd56f2016-06-01 10:37:1112050
bnc691fda62016-08-12 00:43:1612051 const HttpResponseInfo* response = trans.GetResponseInfo();
bnce3dd56f2016-06-01 10:37:1112052 ASSERT_TRUE(response);
12053 ASSERT_TRUE(response->headers);
12054 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12055 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212056 EXPECT_FALSE(response->was_alpn_negotiated);
bnce3dd56f2016-06-01 10:37:1112057
12058 std::string response_data;
bnc691fda62016-08-12 00:43:1612059 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnce3dd56f2016-06-01 10:37:1112060 EXPECT_EQ("hello world", response_data);
12061
zhongyic4de03032017-05-19 04:07:3412062 EXPECT_TRUE(
12063 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnce3dd56f2016-06-01 10:37:1112064}
12065
bnca86731e2017-04-17 12:31:2812066// HTTP/2 Alternative Services should be disabled by default.
bnc8bef8da22016-05-30 01:28:2512067// TODO(bnc): Remove when https://crbug.com/615413 is fixed.
bncd16676a2016-07-20 16:23:0112068TEST_F(HttpNetworkTransactionTest,
bnc8bef8da22016-05-30 01:28:2512069 DisableHTTP2AlternativeServicesWithDifferentHost) {
bnca86731e2017-04-17 12:31:2812070 session_deps_.enable_http2_alternative_service = false;
bncb26024382016-06-29 02:39:4512071
bnc8bef8da22016-05-30 01:28:2512072 HttpRequestInfo request;
12073 request.method = "GET";
bncb26024382016-06-29 02:39:4512074 request.url = GURL("https://www.example.org/");
bnc8bef8da22016-05-30 01:28:2512075 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012076 request.traffic_annotation =
12077 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8bef8da22016-05-30 01:28:2512078
12079 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12080 StaticSocketDataProvider first_data;
12081 first_data.set_connect_data(mock_connect);
12082 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4512083 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612084 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512085 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
bnc8bef8da22016-05-30 01:28:2512086
12087 MockRead data_reads[] = {
12088 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
12089 MockRead(ASYNC, OK),
12090 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112091 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnc8bef8da22016-05-30 01:28:2512092 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
12093
12094 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12095
bnc525e175a2016-06-20 12:36:4012096 HttpServerProperties* http_server_properties =
bnc8bef8da22016-05-30 01:28:2512097 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112098 AlternativeService alternative_service(kProtoHTTP2, "different.example.org",
12099 444);
bnc8bef8da22016-05-30 01:28:2512100 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112101 http_server_properties->SetHttp2AlternativeService(
bnc8bef8da22016-05-30 01:28:2512102 url::SchemeHostPort(request.url), alternative_service, expiration);
12103
bnc691fda62016-08-12 00:43:1612104 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc8bef8da22016-05-30 01:28:2512105 TestCompletionCallback callback;
12106
tfarina42834112016-09-22 13:38:2012107 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc8bef8da22016-05-30 01:28:2512108 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0112109 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc8bef8da22016-05-30 01:28:2512110}
12111
bnce3dd56f2016-06-01 10:37:1112112// Regression test for https://crbug.com/615497:
12113// Alternative Services should be disabled for http origin.
bncd16676a2016-07-20 16:23:0112114TEST_F(HttpNetworkTransactionTest,
bnce3dd56f2016-06-01 10:37:1112115 DisableAlternativeServicesForInsecureOrigin) {
bnce3dd56f2016-06-01 10:37:1112116 HttpRequestInfo request;
12117 request.method = "GET";
12118 request.url = GURL("http://www.example.org/");
12119 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012120 request.traffic_annotation =
12121 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnce3dd56f2016-06-01 10:37:1112122
12123 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12124 StaticSocketDataProvider first_data;
12125 first_data.set_connect_data(mock_connect);
12126 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
12127
12128 MockRead data_reads[] = {
12129 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
12130 MockRead(ASYNC, OK),
12131 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112132 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
bnce3dd56f2016-06-01 10:37:1112133 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
12134
12135 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12136
bnc525e175a2016-06-20 12:36:4012137 HttpServerProperties* http_server_properties =
bnce3dd56f2016-06-01 10:37:1112138 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112139 AlternativeService alternative_service(kProtoHTTP2, "", 444);
bnce3dd56f2016-06-01 10:37:1112140 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112141 http_server_properties->SetHttp2AlternativeService(
bnce3dd56f2016-06-01 10:37:1112142 url::SchemeHostPort(request.url), alternative_service, expiration);
12143
bnc691fda62016-08-12 00:43:1612144 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnce3dd56f2016-06-01 10:37:1112145 TestCompletionCallback callback;
12146
tfarina42834112016-09-22 13:38:2012147 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnce3dd56f2016-06-01 10:37:1112148 // Alternative service is not used, request fails.
robpercival214763f2016-07-01 23:27:0112149 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnce3dd56f2016-06-01 10:37:1112150}
12151
bncd16676a2016-07-20 16:23:0112152TEST_F(HttpNetworkTransactionTest, ClearAlternativeServices) {
bnc4f575852015-10-14 18:35:0812153 // Set an alternative service for origin.
danakj1fd259a02016-04-16 03:17:0912154 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012155 HttpServerProperties* http_server_properties =
12156 session->http_server_properties();
bncb26024382016-06-29 02:39:4512157 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc3472afd2016-11-17 15:27:2112158 AlternativeService alternative_service(kProtoQUIC, "", 80);
bnc4f575852015-10-14 18:35:0812159 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112160 http_server_properties->SetQuicAlternativeService(
12161 test_server, alternative_service, expiration,
12162 session->params().quic_supported_versions);
zhongyic4de03032017-05-19 04:07:3412163 EXPECT_EQ(
12164 1u,
12165 http_server_properties->GetAlternativeServiceInfos(test_server).size());
bnc4f575852015-10-14 18:35:0812166
12167 // Send a clear header.
12168 MockRead data_reads[] = {
12169 MockRead("HTTP/1.1 200 OK\r\n"),
12170 MockRead("Alt-Svc: clear\r\n"),
12171 MockRead("\r\n"),
12172 MockRead("hello world"),
12173 MockRead(SYNCHRONOUS, OK),
12174 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112175 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bnc4f575852015-10-14 18:35:0812176 session_deps_.socket_factory->AddSocketDataProvider(&data);
12177
bncb26024382016-06-29 02:39:4512178 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912179 ssl.ssl_info.cert =
12180 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12181 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512182 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12183
bnc4f575852015-10-14 18:35:0812184 HttpRequestInfo request;
12185 request.method = "GET";
bncb26024382016-06-29 02:39:4512186 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012187 request.traffic_annotation =
12188 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc4f575852015-10-14 18:35:0812189
12190 TestCompletionCallback callback;
12191
bnc691fda62016-08-12 00:43:1612192 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc4f575852015-10-14 18:35:0812193
tfarina42834112016-09-22 13:38:2012194 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112195 EXPECT_THAT(callback.GetResult(rv), IsOk());
bnc4f575852015-10-14 18:35:0812196
bnc691fda62016-08-12 00:43:1612197 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212198 ASSERT_TRUE(response);
12199 ASSERT_TRUE(response->headers);
bnc4f575852015-10-14 18:35:0812200 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12201 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212202 EXPECT_FALSE(response->was_alpn_negotiated);
bnc4f575852015-10-14 18:35:0812203
12204 std::string response_data;
bnc691fda62016-08-12 00:43:1612205 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bnc4f575852015-10-14 18:35:0812206 EXPECT_EQ("hello world", response_data);
12207
zhongyic4de03032017-05-19 04:07:3412208 EXPECT_TRUE(
12209 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bnc4f575852015-10-14 18:35:0812210}
12211
bncd16676a2016-07-20 16:23:0112212TEST_F(HttpNetworkTransactionTest, HonorMultipleAlternativeServiceHeaders) {
bncc958faa2015-07-31 18:14:5212213 MockRead data_reads[] = {
12214 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312215 MockRead("Alt-Svc: h2=\"www.example.com:443\","),
12216 MockRead("h2=\":1234\"\r\n\r\n"),
bncc958faa2015-07-31 18:14:5212217 MockRead("hello world"),
12218 MockRead(SYNCHRONOUS, OK),
12219 };
12220
12221 HttpRequestInfo request;
12222 request.method = "GET";
bncb26024382016-06-29 02:39:4512223 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012224 request.traffic_annotation =
12225 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bncc958faa2015-07-31 18:14:5212226
Ryan Sleevib8d7ea02018-05-07 20:01:0112227 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
bncc958faa2015-07-31 18:14:5212228 session_deps_.socket_factory->AddSocketDataProvider(&data);
12229
bncb26024382016-06-29 02:39:4512230 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912231 ssl.ssl_info.cert =
12232 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12233 ASSERT_TRUE(ssl.ssl_info.cert);
bncb26024382016-06-29 02:39:4512234 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12235
bncc958faa2015-07-31 18:14:5212236 TestCompletionCallback callback;
12237
danakj1fd259a02016-04-16 03:17:0912238 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1612239 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bncc958faa2015-07-31 18:14:5212240
tfarina42834112016-09-22 13:38:2012241 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112242 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
bncc958faa2015-07-31 18:14:5212243
bncb26024382016-06-29 02:39:4512244 url::SchemeHostPort test_server("https", "www.example.org", 443);
bnc525e175a2016-06-20 12:36:4012245 HttpServerProperties* http_server_properties =
12246 session->http_server_properties();
zhongyic4de03032017-05-19 04:07:3412247 EXPECT_TRUE(
12248 http_server_properties->GetAlternativeServiceInfos(test_server).empty());
bncc958faa2015-07-31 18:14:5212249
robpercival214763f2016-07-01 23:27:0112250 EXPECT_THAT(callback.WaitForResult(), IsOk());
bncc958faa2015-07-31 18:14:5212251
bnc691fda62016-08-12 00:43:1612252 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212253 ASSERT_TRUE(response);
12254 ASSERT_TRUE(response->headers);
bncc958faa2015-07-31 18:14:5212255 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12256 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212257 EXPECT_FALSE(response->was_alpn_negotiated);
bncc958faa2015-07-31 18:14:5212258
12259 std::string response_data;
bnc691fda62016-08-12 00:43:1612260 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
bncc958faa2015-07-31 18:14:5212261 EXPECT_EQ("hello world", response_data);
12262
zhongyic4de03032017-05-19 04:07:3412263 AlternativeServiceInfoVector alternative_service_info_vector =
12264 http_server_properties->GetAlternativeServiceInfos(test_server);
12265 ASSERT_EQ(2u, alternative_service_info_vector.size());
12266
12267 AlternativeService alternative_service(kProtoHTTP2, "www.example.com", 443);
12268 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412269 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3412270 AlternativeService alternative_service_2(kProtoHTTP2, "www.example.org",
12271 1234);
12272 EXPECT_EQ(alternative_service_2,
zhongyi422ce352017-06-09 23:28:5412273 alternative_service_info_vector[1].alternative_service());
bncc958faa2015-07-31 18:14:5212274}
12275
bncd16676a2016-07-20 16:23:0112276TEST_F(HttpNetworkTransactionTest, IdentifyQuicBroken) {
zhongyi3d4a55e72016-04-22 20:36:4612277 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0212278 HostPortPair alternative("alternative.example.org", 443);
12279 std::string origin_url = "https://origin.example.org:443";
12280 std::string alternative_url = "https://alternative.example.org:443";
12281
12282 // Negotiate HTTP/1.1 with alternative.example.org.
12283 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612284 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0212285 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12286
12287 // HTTP/1.1 data for request.
12288 MockWrite http_writes[] = {
12289 MockWrite("GET / HTTP/1.1\r\n"
12290 "Host: alternative.example.org\r\n"
12291 "Connection: keep-alive\r\n\r\n"),
12292 };
12293
12294 MockRead http_reads[] = {
12295 MockRead("HTTP/1.1 200 OK\r\n"
12296 "Content-Type: text/html; charset=iso-8859-1\r\n"
12297 "Content-Length: 40\r\n\r\n"
12298 "first HTTP/1.1 response from alternative"),
12299 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112300 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0212301 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12302
12303 StaticSocketDataProvider data_refused;
12304 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12305 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12306
zhongyi3d4a55e72016-04-22 20:36:4612307 // Set up a QUIC alternative service for server.
danakj1fd259a02016-04-16 03:17:0912308 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012309 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0212310 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2112311 AlternativeService alternative_service(kProtoQUIC, alternative);
zhongyi48704c182015-12-07 07:52:0212312 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112313 http_server_properties->SetQuicAlternativeService(
12314 server, alternative_service, expiration,
12315 HttpNetworkSession::Params().quic_supported_versions);
zhongyi48704c182015-12-07 07:52:0212316 // Mark the QUIC alternative service as broken.
12317 http_server_properties->MarkAlternativeServiceBroken(alternative_service);
12318
zhongyi48704c182015-12-07 07:52:0212319 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4612320 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0212321 request.method = "GET";
12322 request.url = GURL(origin_url);
Ramin Halavatib5e433e62018-02-07 07:41:1012323 request.traffic_annotation =
12324 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12325
zhongyi48704c182015-12-07 07:52:0212326 TestCompletionCallback callback;
12327 NetErrorDetails details;
12328 EXPECT_FALSE(details.quic_broken);
12329
tfarina42834112016-09-22 13:38:2012330 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1612331 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0212332 EXPECT_TRUE(details.quic_broken);
12333}
12334
bncd16676a2016-07-20 16:23:0112335TEST_F(HttpNetworkTransactionTest, IdentifyQuicNotBroken) {
zhongyi3d4a55e72016-04-22 20:36:4612336 url::SchemeHostPort server("https", "origin.example.org", 443);
zhongyi48704c182015-12-07 07:52:0212337 HostPortPair alternative1("alternative1.example.org", 443);
12338 HostPortPair alternative2("alternative2.example.org", 443);
12339 std::string origin_url = "https://origin.example.org:443";
12340 std::string alternative_url1 = "https://alternative1.example.org:443";
12341 std::string alternative_url2 = "https://alternative2.example.org:443";
12342
12343 // Negotiate HTTP/1.1 with alternative1.example.org.
12344 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612345 ssl.next_proto = kProtoHTTP11;
zhongyi48704c182015-12-07 07:52:0212346 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12347
12348 // HTTP/1.1 data for request.
12349 MockWrite http_writes[] = {
12350 MockWrite("GET / HTTP/1.1\r\n"
12351 "Host: alternative1.example.org\r\n"
12352 "Connection: keep-alive\r\n\r\n"),
12353 };
12354
12355 MockRead http_reads[] = {
12356 MockRead("HTTP/1.1 200 OK\r\n"
12357 "Content-Type: text/html; charset=iso-8859-1\r\n"
12358 "Content-Length: 40\r\n\r\n"
12359 "first HTTP/1.1 response from alternative1"),
12360 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112361 StaticSocketDataProvider http_data(http_reads, http_writes);
zhongyi48704c182015-12-07 07:52:0212362 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12363
12364 StaticSocketDataProvider data_refused;
12365 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12366 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12367
danakj1fd259a02016-04-16 03:17:0912368 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4012369 HttpServerProperties* http_server_properties =
zhongyi48704c182015-12-07 07:52:0212370 session->http_server_properties();
12371
zhongyi3d4a55e72016-04-22 20:36:4612372 // Set up two QUIC alternative services for server.
zhongyi48704c182015-12-07 07:52:0212373 AlternativeServiceInfoVector alternative_service_info_vector;
12374 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
12375
bnc3472afd2016-11-17 15:27:2112376 AlternativeService alternative_service1(kProtoQUIC, alternative1);
zhongyie537a002017-06-27 16:48:2112377 alternative_service_info_vector.push_back(
12378 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
12379 alternative_service1, expiration,
12380 session->params().quic_supported_versions));
bnc3472afd2016-11-17 15:27:2112381 AlternativeService alternative_service2(kProtoQUIC, alternative2);
zhongyie537a002017-06-27 16:48:2112382 alternative_service_info_vector.push_back(
12383 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
12384 alternative_service2, expiration,
12385 session->params().quic_supported_versions));
zhongyi48704c182015-12-07 07:52:0212386
12387 http_server_properties->SetAlternativeServices(
zhongyi3d4a55e72016-04-22 20:36:4612388 server, alternative_service_info_vector);
zhongyi48704c182015-12-07 07:52:0212389
12390 // Mark one of the QUIC alternative service as broken.
12391 http_server_properties->MarkAlternativeServiceBroken(alternative_service1);
zhongyic4de03032017-05-19 04:07:3412392 EXPECT_EQ(2u,
12393 http_server_properties->GetAlternativeServiceInfos(server).size());
zhongyi48704c182015-12-07 07:52:0212394
zhongyi48704c182015-12-07 07:52:0212395 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4612396 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
zhongyi48704c182015-12-07 07:52:0212397 request.method = "GET";
12398 request.url = GURL(origin_url);
Ramin Halavatib5e433e62018-02-07 07:41:1012399 request.traffic_annotation =
12400 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
12401
zhongyi48704c182015-12-07 07:52:0212402 TestCompletionCallback callback;
12403 NetErrorDetails details;
12404 EXPECT_FALSE(details.quic_broken);
12405
tfarina42834112016-09-22 13:38:2012406 trans.Start(&request, callback.callback(), NetLogWithSource());
bnc691fda62016-08-12 00:43:1612407 trans.PopulateNetErrorDetails(&details);
zhongyi48704c182015-12-07 07:52:0212408 EXPECT_FALSE(details.quic_broken);
12409}
12410
bncd16676a2016-07-20 16:23:0112411TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
[email protected]564b4912010-03-09 16:30:4212412 HttpRequestInfo request;
12413 request.method = "GET";
bncb26024382016-06-29 02:39:4512414 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012415 request.traffic_annotation =
12416 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]564b4912010-03-09 16:30:4212417
[email protected]d973e99a2012-02-17 21:02:3612418 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]564b4912010-03-09 16:30:4212419 StaticSocketDataProvider first_data;
12420 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712421 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
bncb26024382016-06-29 02:39:4512422 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612423 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512424 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]564b4912010-03-09 16:30:4212425
12426 MockRead data_reads[] = {
12427 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12428 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612429 MockRead(ASYNC, OK),
[email protected]564b4912010-03-09 16:30:4212430 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112431 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712432 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]564b4912010-03-09 16:30:4212433
danakj1fd259a02016-04-16 03:17:0912434 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]564b4912010-03-09 16:30:4212435
bnc525e175a2016-06-20 12:36:4012436 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312437 session->http_server_properties();
zhongyi3d4a55e72016-04-22 20:36:4612438 const url::SchemeHostPort server(request.url);
[email protected]3912662a32011-10-04 00:51:1112439 // Port must be < 1024, or the header will be ignored (since initial port was
12440 // port 80 (another restricted port).
zhongyie537a002017-06-27 16:48:2112441 // Port is ignored by MockConnect anyway.
12442 const AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12443 666);
bnc7dc7e1b42015-07-28 14:43:1212444 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112445 http_server_properties->SetHttp2AlternativeService(
12446 server, alternative_service, expiration);
[email protected]564b4912010-03-09 16:30:4212447
bnc691fda62016-08-12 00:43:1612448 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112449 TestCompletionCallback callback;
[email protected]564b4912010-03-09 16:30:4212450
tfarina42834112016-09-22 13:38:2012451 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112452 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12453 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]564b4912010-03-09 16:30:4212454
bnc691fda62016-08-12 00:43:1612455 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212456 ASSERT_TRUE(response);
12457 ASSERT_TRUE(response->headers);
[email protected]564b4912010-03-09 16:30:4212458 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12459
12460 std::string response_data;
bnc691fda62016-08-12 00:43:1612461 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]564b4912010-03-09 16:30:4212462 EXPECT_EQ("hello world", response_data);
12463
zhongyic4de03032017-05-19 04:07:3412464 const AlternativeServiceInfoVector alternative_service_info_vector =
12465 http_server_properties->GetAlternativeServiceInfos(server);
12466 ASSERT_EQ(1u, alternative_service_info_vector.size());
12467 EXPECT_EQ(alternative_service,
zhongyi422ce352017-06-09 23:28:5412468 alternative_service_info_vector[0].alternative_service());
zhongyic4de03032017-05-19 04:07:3412469 EXPECT_TRUE(
12470 http_server_properties->IsAlternativeServiceBroken(alternative_service));
[email protected]564b4912010-03-09 16:30:4212471}
12472
bnc55ff9da2015-08-19 18:42:3512473// Ensure that we are not allowed to redirect traffic via an alternate protocol
12474// to an unrestricted (port >= 1024) when the original traffic was on a
12475// restricted port (port < 1024). Ensure that we can redirect in all other
12476// cases.
bncd16676a2016-07-20 16:23:0112477TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) {
[email protected]3912662a32011-10-04 00:51:1112478 HttpRequestInfo restricted_port_request;
12479 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512480 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1112481 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012482 restricted_port_request.traffic_annotation =
12483 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112484
[email protected]d973e99a2012-02-17 21:02:3612485 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112486 StaticSocketDataProvider first_data;
12487 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712488 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112489
12490 MockRead data_reads[] = {
12491 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12492 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612493 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112494 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112495 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712496 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512497 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612498 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512499 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1112500
danakj1fd259a02016-04-16 03:17:0912501 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112502
bnc525e175a2016-06-20 12:36:4012503 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312504 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112505 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2112506 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12507 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212508 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112509 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612510 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012511 expiration);
[email protected]3912662a32011-10-04 00:51:1112512
bnc691fda62016-08-12 00:43:1612513 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112514 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112515
tfarina42834112016-09-22 13:38:2012516 int rv = trans.Start(&restricted_port_request, callback.callback(),
12517 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112518 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112519 // Invalid change to unrestricted port should fail.
robpercival214763f2016-07-01 23:27:0112520 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED));
[email protected]c54c6962013-02-01 04:53:1912521}
[email protected]3912662a32011-10-04 00:51:1112522
bnc55ff9da2015-08-19 18:42:3512523// Ensure that we are allowed to redirect traffic via an alternate protocol to
12524// an unrestricted (port >= 1024) when the original traffic was on a restricted
12525// port (port < 1024) if we set |enable_user_alternate_protocol_ports|.
bncd16676a2016-07-20 16:23:0112526TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedPermitted) {
[email protected]bb88e1d32013-05-03 23:11:0712527 session_deps_.enable_user_alternate_protocol_ports = true;
[email protected]c54c6962013-02-01 04:53:1912528
12529 HttpRequestInfo restricted_port_request;
12530 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512531 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]c54c6962013-02-01 04:53:1912532 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012533 restricted_port_request.traffic_annotation =
12534 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]c54c6962013-02-01 04:53:1912535
12536 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
12537 StaticSocketDataProvider first_data;
12538 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712539 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]c54c6962013-02-01 04:53:1912540
12541 MockRead data_reads[] = {
12542 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12543 MockRead("hello world"),
12544 MockRead(ASYNC, OK),
12545 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112546 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712547 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512548 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612549 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512550 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]c54c6962013-02-01 04:53:1912551
danakj1fd259a02016-04-16 03:17:0912552 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]c54c6962013-02-01 04:53:1912553
bnc525e175a2016-06-20 12:36:4012554 HttpServerProperties* http_server_properties =
[email protected]c54c6962013-02-01 04:53:1912555 session->http_server_properties();
12556 const int kUnrestrictedAlternatePort = 1024;
bnc3472afd2016-11-17 15:27:2112557 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12558 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212559 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112560 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612561 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012562 expiration);
[email protected]c54c6962013-02-01 04:53:1912563
bnc691fda62016-08-12 00:43:1612564 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]c54c6962013-02-01 04:53:1912565 TestCompletionCallback callback;
12566
tfarina42834112016-09-22 13:38:2012567 EXPECT_EQ(ERR_IO_PENDING,
12568 trans.Start(&restricted_port_request, callback.callback(),
12569 NetLogWithSource()));
[email protected]c54c6962013-02-01 04:53:1912570 // Change to unrestricted port should succeed.
robpercival214763f2016-07-01 23:27:0112571 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112572}
12573
bnc55ff9da2015-08-19 18:42:3512574// Ensure that we are not allowed to redirect traffic via an alternate protocol
12575// to an unrestricted (port >= 1024) when the original traffic was on a
12576// restricted port (port < 1024). Ensure that we can redirect in all other
12577// cases.
bncd16676a2016-07-20 16:23:0112578TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) {
[email protected]3912662a32011-10-04 00:51:1112579 HttpRequestInfo restricted_port_request;
12580 restricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512581 restricted_port_request.url = GURL("https://www.example.org:1023/");
[email protected]3912662a32011-10-04 00:51:1112582 restricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012583 restricted_port_request.traffic_annotation =
12584 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112585
[email protected]d973e99a2012-02-17 21:02:3612586 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112587 StaticSocketDataProvider first_data;
12588 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712589 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112590
12591 MockRead data_reads[] = {
12592 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12593 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612594 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112595 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112596 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712597 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1112598
bncb26024382016-06-29 02:39:4512599 SSLSocketDataProvider ssl(ASYNC, OK);
12600 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12601
danakj1fd259a02016-04-16 03:17:0912602 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112603
bnc525e175a2016-06-20 12:36:4012604 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312605 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112606 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2112607 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12608 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212609 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112610 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612611 url::SchemeHostPort(restricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012612 expiration);
[email protected]3912662a32011-10-04 00:51:1112613
bnc691fda62016-08-12 00:43:1612614 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112615 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112616
tfarina42834112016-09-22 13:38:2012617 int rv = trans.Start(&restricted_port_request, callback.callback(),
12618 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112619 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112620 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0112621 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112622}
12623
bnc55ff9da2015-08-19 18:42:3512624// Ensure that we are not allowed to redirect traffic via an alternate protocol
12625// to an unrestricted (port >= 1024) when the original traffic was on a
12626// restricted port (port < 1024). Ensure that we can redirect in all other
12627// cases.
bncd16676a2016-07-20 16:23:0112628TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) {
[email protected]3912662a32011-10-04 00:51:1112629 HttpRequestInfo unrestricted_port_request;
12630 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512631 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1112632 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012633 unrestricted_port_request.traffic_annotation =
12634 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112635
[email protected]d973e99a2012-02-17 21:02:3612636 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112637 StaticSocketDataProvider first_data;
12638 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712639 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112640
12641 MockRead data_reads[] = {
12642 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12643 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612644 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112645 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112646 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712647 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
bncb26024382016-06-29 02:39:4512648 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612649 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512650 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]3912662a32011-10-04 00:51:1112651
danakj1fd259a02016-04-16 03:17:0912652 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112653
bnc525e175a2016-06-20 12:36:4012654 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312655 session->http_server_properties();
[email protected]3912662a32011-10-04 00:51:1112656 const int kRestrictedAlternatePort = 80;
bnc3472afd2016-11-17 15:27:2112657 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12658 kRestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212659 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112660 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612661 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012662 expiration);
[email protected]3912662a32011-10-04 00:51:1112663
bnc691fda62016-08-12 00:43:1612664 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112665 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112666
bnc691fda62016-08-12 00:43:1612667 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2012668 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112669 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112670 // Valid change to restricted port should pass.
robpercival214763f2016-07-01 23:27:0112671 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112672}
12673
bnc55ff9da2015-08-19 18:42:3512674// Ensure that we are not allowed to redirect traffic via an alternate protocol
12675// to an unrestricted (port >= 1024) when the original traffic was on a
12676// restricted port (port < 1024). Ensure that we can redirect in all other
12677// cases.
bncd16676a2016-07-20 16:23:0112678TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) {
[email protected]3912662a32011-10-04 00:51:1112679 HttpRequestInfo unrestricted_port_request;
12680 unrestricted_port_request.method = "GET";
bncb26024382016-06-29 02:39:4512681 unrestricted_port_request.url = GURL("https://www.example.org:1024/");
[email protected]3912662a32011-10-04 00:51:1112682 unrestricted_port_request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1012683 unrestricted_port_request.traffic_annotation =
12684 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]3912662a32011-10-04 00:51:1112685
[email protected]d973e99a2012-02-17 21:02:3612686 MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
[email protected]3912662a32011-10-04 00:51:1112687 StaticSocketDataProvider first_data;
12688 first_data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0712689 session_deps_.socket_factory->AddSocketDataProvider(&first_data);
[email protected]3912662a32011-10-04 00:51:1112690
12691 MockRead data_reads[] = {
12692 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12693 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612694 MockRead(ASYNC, OK),
[email protected]3912662a32011-10-04 00:51:1112695 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112696 StaticSocketDataProvider second_data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712697 session_deps_.socket_factory->AddSocketDataProvider(&second_data);
[email protected]3912662a32011-10-04 00:51:1112698
bncb26024382016-06-29 02:39:4512699 SSLSocketDataProvider ssl(ASYNC, OK);
12700 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12701
danakj1fd259a02016-04-16 03:17:0912702 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]3912662a32011-10-04 00:51:1112703
bnc525e175a2016-06-20 12:36:4012704 HttpServerProperties* http_server_properties =
[email protected]17291a022011-10-10 07:32:5312705 session->http_server_properties();
bnc0bbb02622015-07-23 10:06:2212706 const int kUnrestrictedAlternatePort = 1025;
bnc3472afd2016-11-17 15:27:2112707 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12708 kUnrestrictedAlternatePort);
bnc7dc7e1b42015-07-28 14:43:1212709 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112710 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612711 url::SchemeHostPort(unrestricted_port_request.url), alternative_service,
rchdc7b9052016-03-17 20:51:5012712 expiration);
[email protected]3912662a32011-10-04 00:51:1112713
bnc691fda62016-08-12 00:43:1612714 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4112715 TestCompletionCallback callback;
[email protected]3912662a32011-10-04 00:51:1112716
bnc691fda62016-08-12 00:43:1612717 int rv = trans.Start(&unrestricted_port_request, callback.callback(),
tfarina42834112016-09-22 13:38:2012718 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112719 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]3912662a32011-10-04 00:51:1112720 // Valid change to an unrestricted port should pass.
robpercival214763f2016-07-01 23:27:0112721 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]3912662a32011-10-04 00:51:1112722}
12723
bnc55ff9da2015-08-19 18:42:3512724// Ensure that we are not allowed to redirect traffic via an alternate protocol
Xida Chen9bfe0b62018-04-24 19:52:2112725// to an unsafe port, and that we resume the second HttpStreamFactory::Job once
12726// the alternate protocol request fails.
bncd16676a2016-07-20 16:23:0112727TEST_F(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
[email protected]eb6234e2012-01-19 01:50:0212728 HttpRequestInfo request;
12729 request.method = "GET";
bncce36dca22015-04-21 22:11:2312730 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012731 request.traffic_annotation =
12732 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]eb6234e2012-01-19 01:50:0212733
12734 // The alternate protocol request will error out before we attempt to connect,
12735 // so only the standard HTTP request will try to connect.
12736 MockRead data_reads[] = {
12737 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
12738 MockRead("hello world"),
[email protected]8ddf8322012-02-23 18:08:0612739 MockRead(ASYNC, OK),
[email protected]eb6234e2012-01-19 01:50:0212740 };
Ryan Sleevib8d7ea02018-05-07 20:01:0112741 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712742 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]eb6234e2012-01-19 01:50:0212743
danakj1fd259a02016-04-16 03:17:0912744 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]eb6234e2012-01-19 01:50:0212745
bnc525e175a2016-06-20 12:36:4012746 HttpServerProperties* http_server_properties =
[email protected]eb6234e2012-01-19 01:50:0212747 session->http_server_properties();
12748 const int kUnsafePort = 7;
bnc3472afd2016-11-17 15:27:2112749 AlternativeService alternative_service(kProtoHTTP2, "www.example.org",
12750 kUnsafePort);
bnc7dc7e1b42015-07-28 14:43:1212751 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2112752 http_server_properties->SetHttp2AlternativeService(
zhongyi3d4a55e72016-04-22 20:36:4612753 url::SchemeHostPort(request.url), alternative_service, expiration);
[email protected]eb6234e2012-01-19 01:50:0212754
bnc691fda62016-08-12 00:43:1612755 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]eb6234e2012-01-19 01:50:0212756 TestCompletionCallback callback;
12757
tfarina42834112016-09-22 13:38:2012758 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112759 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]eb6234e2012-01-19 01:50:0212760 // The HTTP request should succeed.
robpercival214763f2016-07-01 23:27:0112761 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212762
bnc691fda62016-08-12 00:43:1612763 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5212764 ASSERT_TRUE(response);
12765 ASSERT_TRUE(response->headers);
[email protected]eb6234e2012-01-19 01:50:0212766 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12767
12768 std::string response_data;
bnc691fda62016-08-12 00:43:1612769 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]eb6234e2012-01-19 01:50:0212770 EXPECT_EQ("hello world", response_data);
12771}
12772
bncd16676a2016-07-20 16:23:0112773TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
[email protected]2ff8b312010-04-26 22:20:5412774 HttpRequestInfo request;
12775 request.method = "GET";
bncb26024382016-06-29 02:39:4512776 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012777 request.traffic_annotation =
12778 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5412779
12780 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212781 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312782 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212783 MockRead("\r\n"),
12784 MockRead("hello world"),
12785 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12786 MockRead(ASYNC, OK)};
[email protected]2ff8b312010-04-26 22:20:5412787
Ryan Sleevib8d7ea02018-05-07 20:01:0112788 StaticSocketDataProvider first_transaction(data_reads,
12789 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712790 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4512791 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3612792 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4512793 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5412794
bnc032658ba2016-09-26 18:17:1512795 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5412796
Ryan Hamilton0239aac2018-05-19 00:03:1312797 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4512798 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4112799 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5412800
Raul Tambre94493c652019-03-11 17:18:3512801 spdy::SpdySerializedFrame resp(
12802 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1312803 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5412804 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112805 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5412806 };
12807
Ryan Sleevib8d7ea02018-05-07 20:01:0112808 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712809 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5412810
[email protected]d973e99a2012-02-17 21:02:3612811 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112812 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5512813 hanging_non_alternate_protocol_socket.set_connect_data(
12814 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0712815 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5512816 &hanging_non_alternate_protocol_socket);
12817
[email protected]49639fa2011-12-20 23:22:4112818 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5412819
danakj1fd259a02016-04-16 03:17:0912820 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5812821 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1912822 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412823
tfarina42834112016-09-22 13:38:2012824 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112825 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12826 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412827
12828 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212829 ASSERT_TRUE(response);
12830 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5412831 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12832
12833 std::string response_data;
robpercival214763f2016-07-01 23:27:0112834 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412835 EXPECT_EQ("hello world", response_data);
12836
bnc87dcefc2017-05-25 12:47:5812837 trans =
Jeremy Roman0579ed62017-08-29 15:56:1912838 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5412839
tfarina42834112016-09-22 13:38:2012840 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112841 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12842 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412843
12844 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5212845 ASSERT_TRUE(response);
12846 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212847 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5312848 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212849 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5412850
robpercival214763f2016-07-01 23:27:0112851 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5412852 EXPECT_EQ("hello!", response_data);
[email protected]2ff8b312010-04-26 22:20:5412853}
12854
bncd16676a2016-07-20 16:23:0112855TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
[email protected]2d6728692011-03-12 01:39:5512856 HttpRequestInfo request;
12857 request.method = "GET";
bncb26024382016-06-29 02:39:4512858 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012859 request.traffic_annotation =
12860 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512861
bncb26024382016-06-29 02:39:4512862 // First transaction receives Alt-Svc header over HTTP/1.1.
[email protected]2d6728692011-03-12 01:39:5512863 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212864 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312865 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212866 MockRead("\r\n"),
12867 MockRead("hello world"),
12868 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12869 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512870 };
12871
Ryan Sleevib8d7ea02018-05-07 20:01:0112872 StaticSocketDataProvider http11_data(data_reads, base::span<MockWrite>());
bncb26024382016-06-29 02:39:4512873 session_deps_.socket_factory->AddSocketDataProvider(&http11_data);
[email protected]2d6728692011-03-12 01:39:5512874
bncb26024382016-06-29 02:39:4512875 SSLSocketDataProvider ssl_http11(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912876 ssl_http11.ssl_info.cert =
12877 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12878 ASSERT_TRUE(ssl_http11.ssl_info.cert);
bncb26024382016-06-29 02:39:4512879 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
12880
12881 // Second transaction starts an alternative and a non-alternative Job.
12882 // Both sockets hang.
[email protected]d973e99a2012-02-17 21:02:3612883 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0112884 StaticSocketDataProvider hanging_socket1;
mmenkecc2298e2015-12-07 18:20:1812885 hanging_socket1.set_connect_data(never_finishing_connect);
mmenkecc2298e2015-12-07 18:20:1812886 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket1);
12887
Ryan Sleevib8d7ea02018-05-07 20:01:0112888 StaticSocketDataProvider hanging_socket2;
mmenkecc2298e2015-12-07 18:20:1812889 hanging_socket2.set_connect_data(never_finishing_connect);
12890 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket2);
[email protected]2d6728692011-03-12 01:39:5512891
bncb26024382016-06-29 02:39:4512892 // Third transaction starts an alternative and a non-alternative job.
12893 // The non-alternative job hangs, but the alternative one succeeds.
12894 // The second transaction, still pending, binds to this socket.
Ryan Hamilton0239aac2018-05-19 00:03:1312895 spdy::SpdySerializedFrame req1(
bncb26024382016-06-29 02:39:4512896 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1312897 spdy::SpdySerializedFrame req2(
bncb26024382016-06-29 02:39:4512898 spdy_util_.ConstructSpdyGet("https://www.example.org/", 3, LOWEST));
[email protected]2d6728692011-03-12 01:39:5512899 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4112900 CreateMockWrite(req1, 0), CreateMockWrite(req2, 1),
[email protected]2d6728692011-03-12 01:39:5512901 };
Raul Tambre94493c652019-03-11 17:18:3512902 spdy::SpdySerializedFrame resp1(
12903 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1312904 spdy::SpdySerializedFrame data1(spdy_util_.ConstructSpdyDataFrame(1, true));
Raul Tambre94493c652019-03-11 17:18:3512905 spdy::SpdySerializedFrame resp2(
12906 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1312907 spdy::SpdySerializedFrame data2(spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]2d6728692011-03-12 01:39:5512908 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4112909 CreateMockRead(resp1, 2), CreateMockRead(data1, 3),
12910 CreateMockRead(resp2, 4), CreateMockRead(data2, 5),
rch8e6c6c42015-05-01 14:05:1312911 MockRead(ASYNC, 0, 6),
[email protected]2d6728692011-03-12 01:39:5512912 };
12913
Ryan Sleevib8d7ea02018-05-07 20:01:0112914 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0712915 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2d6728692011-03-12 01:39:5512916
bnc032658ba2016-09-26 18:17:1512917 AddSSLSocketData();
bncb26024382016-06-29 02:39:4512918
Ryan Sleevib8d7ea02018-05-07 20:01:0112919 StaticSocketDataProvider hanging_socket3;
mmenkecc2298e2015-12-07 18:20:1812920 hanging_socket3.set_connect_data(never_finishing_connect);
12921 session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket3);
[email protected]2d6728692011-03-12 01:39:5512922
danakj1fd259a02016-04-16 03:17:0912923 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]49639fa2011-12-20 23:22:4112924 TestCompletionCallback callback1;
[email protected]90499482013-06-01 00:39:5012925 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5512926
tfarina42834112016-09-22 13:38:2012927 int rv = trans1.Start(&request, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112928 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
12929 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512930
12931 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5212932 ASSERT_TRUE(response);
12933 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5512934 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
12935
12936 std::string response_data;
robpercival214763f2016-07-01 23:27:0112937 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512938 EXPECT_EQ("hello world", response_data);
12939
[email protected]49639fa2011-12-20 23:22:4112940 TestCompletionCallback callback2;
[email protected]90499482013-06-01 00:39:5012941 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012942 rv = trans2.Start(&request, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112943 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512944
[email protected]49639fa2011-12-20 23:22:4112945 TestCompletionCallback callback3;
[email protected]90499482013-06-01 00:39:5012946 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2012947 rv = trans3.Start(&request, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0112948 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]2d6728692011-03-12 01:39:5512949
robpercival214763f2016-07-01 23:27:0112950 EXPECT_THAT(callback2.WaitForResult(), IsOk());
12951 EXPECT_THAT(callback3.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5512952
12953 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5212954 ASSERT_TRUE(response);
12955 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212956 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512957 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212958 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112959 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512960 EXPECT_EQ("hello!", response_data);
12961
12962 response = trans3.GetResponseInfo();
wezca1070932016-05-26 20:30:5212963 ASSERT_TRUE(response);
12964 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0212965 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]2d6728692011-03-12 01:39:5512966 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5212967 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0112968 ASSERT_THAT(ReadTransaction(&trans3, &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5512969 EXPECT_EQ("hello!", response_data);
[email protected]2d6728692011-03-12 01:39:5512970}
12971
bncd16676a2016-07-20 16:23:0112972TEST_F(HttpNetworkTransactionTest, StallAlternativeServiceForNpnSpdy) {
Bence Békybcae37092018-06-12 04:18:5312973 session_deps_.host_resolver->set_synchronous_mode(true);
12974
[email protected]2d6728692011-03-12 01:39:5512975 HttpRequestInfo request;
12976 request.method = "GET";
bncb26024382016-06-29 02:39:4512977 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1012978 request.traffic_annotation =
12979 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2d6728692011-03-12 01:39:5512980
12981 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5212982 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4312983 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5212984 MockRead("\r\n"),
12985 MockRead("hello world"),
12986 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
12987 MockRead(ASYNC, OK),
[email protected]2d6728692011-03-12 01:39:5512988 };
12989
Ryan Sleevib8d7ea02018-05-07 20:01:0112990 StaticSocketDataProvider first_transaction(data_reads,
12991 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0712992 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
[email protected]2d6728692011-03-12 01:39:5512993
[email protected]8ddf8322012-02-23 18:08:0612994 SSLSocketDataProvider ssl(ASYNC, OK);
Ryan Sleevi4f832092017-11-21 23:25:4912995 ssl.ssl_info.cert =
12996 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
12997 ASSERT_TRUE(ssl.ssl_info.cert);
[email protected]bb88e1d32013-05-03 23:11:0712998 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5512999
[email protected]d973e99a2012-02-17 21:02:3613000 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113001 StaticSocketDataProvider hanging_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5513002 hanging_alternate_protocol_socket.set_connect_data(
13003 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0713004 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5513005 &hanging_alternate_protocol_socket);
13006
bncb26024382016-06-29 02:39:4513007 // 2nd request is just a copy of the first one, over HTTP/1.1 again.
Ryan Sleevib8d7ea02018-05-07 20:01:0113008 StaticSocketDataProvider second_transaction(data_reads,
13009 base::span<MockWrite>());
mmenkecc2298e2015-12-07 18:20:1813010 session_deps_.socket_factory->AddSocketDataProvider(&second_transaction);
bncb26024382016-06-29 02:39:4513011 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]2d6728692011-03-12 01:39:5513012
[email protected]49639fa2011-12-20 23:22:4113013 TestCompletionCallback callback;
[email protected]2d6728692011-03-12 01:39:5513014
danakj1fd259a02016-04-16 03:17:0913015 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813016 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913017 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5513018
tfarina42834112016-09-22 13:38:2013019 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113020 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13021 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5513022
13023 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213024 ASSERT_TRUE(response);
13025 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5513026 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13027
13028 std::string response_data;
robpercival214763f2016-07-01 23:27:0113029 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513030 EXPECT_EQ("hello world", response_data);
13031
bnc87dcefc2017-05-25 12:47:5813032 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913033 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2d6728692011-03-12 01:39:5513034
tfarina42834112016-09-22 13:38:2013035 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113036 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13037 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2d6728692011-03-12 01:39:5513038
13039 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213040 ASSERT_TRUE(response);
13041 ASSERT_TRUE(response->headers);
[email protected]2d6728692011-03-12 01:39:5513042 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13043 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213044 EXPECT_FALSE(response->was_alpn_negotiated);
[email protected]2d6728692011-03-12 01:39:5513045
robpercival214763f2016-07-01 23:27:0113046 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2d6728692011-03-12 01:39:5513047 EXPECT_EQ("hello world", response_data);
[email protected]2d6728692011-03-12 01:39:5513048}
13049
bnc2e884782016-08-11 19:45:1913050// Test that proxy is resolved using the origin url,
13051// regardless of the alternative server.
13052TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) {
13053 // Configure proxy to bypass www.example.org, which is the origin URL.
13054 ProxyConfig proxy_config;
13055 proxy_config.proxy_rules().ParseFromString("myproxy:70");
13056 proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org");
Ramin Halavatica8d5252018-03-12 05:33:4913057 auto proxy_config_service = std::make_unique<ProxyConfigServiceFixed>(
13058 ProxyConfigWithAnnotation(proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS));
bnc2e884782016-08-11 19:45:1913059
13060 CapturingProxyResolver capturing_proxy_resolver;
Jeremy Roman0579ed62017-08-29 15:56:1913061 auto proxy_resolver_factory = std::make_unique<CapturingProxyResolverFactory>(
bnc2e884782016-08-11 19:45:1913062 &capturing_proxy_resolver);
13063
13064 TestNetLog net_log;
13065
Bence Béky53a5aef2018-03-29 21:54:1213066 session_deps_.proxy_resolution_service =
13067 std::make_unique<ProxyResolutionService>(
13068 std::move(proxy_config_service), std::move(proxy_resolver_factory),
13069 &net_log);
bnc2e884782016-08-11 19:45:1913070
13071 session_deps_.net_log = &net_log;
13072
13073 // Configure alternative service with a hostname that is not bypassed by the
13074 // proxy.
13075 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
13076 HttpServerProperties* http_server_properties =
13077 session->http_server_properties();
13078 url::SchemeHostPort server("https", "www.example.org", 443);
13079 HostPortPair alternative("www.example.com", 443);
bnc3472afd2016-11-17 15:27:2113080 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc2e884782016-08-11 19:45:1913081 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2113082 http_server_properties->SetHttp2AlternativeService(
13083 server, alternative_service, expiration);
bnc2e884782016-08-11 19:45:1913084
13085 // Non-alternative job should hang.
13086 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113087 StaticSocketDataProvider hanging_alternate_protocol_socket;
bnc2e884782016-08-11 19:45:1913088 hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect);
13089 session_deps_.socket_factory->AddSocketDataProvider(
13090 &hanging_alternate_protocol_socket);
13091
bnc032658ba2016-09-26 18:17:1513092 AddSSLSocketData();
bnc2e884782016-08-11 19:45:1913093
13094 HttpRequestInfo request;
13095 request.method = "GET";
13096 request.url = GURL("https://www.example.org/");
13097 request.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1013098 request.traffic_annotation =
13099 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc2e884782016-08-11 19:45:1913100
Ryan Hamilton0239aac2018-05-19 00:03:1313101 spdy::SpdySerializedFrame req(
bnc2e884782016-08-11 19:45:1913102 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
13103
13104 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
13105
Ryan Hamilton0239aac2018-05-19 00:03:1313106 spdy::SpdySerializedFrame resp(
13107 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
13108 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
bnc2e884782016-08-11 19:45:1913109 MockRead spdy_reads[] = {
13110 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
13111 };
13112
Ryan Sleevib8d7ea02018-05-07 20:01:0113113 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
bnc2e884782016-08-11 19:45:1913114 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
13115
13116 TestCompletionCallback callback;
13117
13118 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
13119
tfarina42834112016-09-22 13:38:2013120 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc2e884782016-08-11 19:45:1913121 EXPECT_THAT(callback.GetResult(rv), IsOk());
13122
13123 const HttpResponseInfo* response = trans.GetResponseInfo();
13124 ASSERT_TRUE(response);
13125 ASSERT_TRUE(response->headers);
13126 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13127 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213128 EXPECT_TRUE(response->was_alpn_negotiated);
bnc2e884782016-08-11 19:45:1913129
13130 std::string response_data;
13131 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
13132 EXPECT_EQ("hello!", response_data);
13133
13134 // Origin host bypasses proxy, no resolution should have happened.
13135 ASSERT_TRUE(capturing_proxy_resolver.resolved().empty());
13136}
13137
bncd16676a2016-07-20 16:23:0113138TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) {
[email protected]631f1322010-04-30 17:59:1113139 ProxyConfig proxy_config;
[email protected]d911f1b2010-05-05 22:39:4213140 proxy_config.set_auto_detect(true);
13141 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
[email protected]2227c692010-05-04 15:36:1113142
sammc5dd160c2015-04-02 02:43:1313143 CapturingProxyResolver capturing_proxy_resolver;
Ramin Halavatica8d5252018-03-12 05:33:4913144 session_deps_.proxy_resolution_service =
13145 std::make_unique<ProxyResolutionService>(
13146 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
13147 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
13148 std::make_unique<CapturingProxyResolverFactory>(
13149 &capturing_proxy_resolver),
13150 nullptr);
vishal.b62985ca92015-04-17 08:45:5113151 TestNetLog net_log;
[email protected]bb88e1d32013-05-03 23:11:0713152 session_deps_.net_log = &net_log;
[email protected]631f1322010-04-30 17:59:1113153
13154 HttpRequestInfo request;
13155 request.method = "GET";
bncb26024382016-06-29 02:39:4513156 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013157 request.traffic_annotation =
13158 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]631f1322010-04-30 17:59:1113159
13160 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213161 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313162 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213163 MockRead("\r\n"),
13164 MockRead("hello world"),
13165 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
13166 MockRead(ASYNC, OK),
[email protected]631f1322010-04-30 17:59:1113167 };
13168
Ryan Sleevib8d7ea02018-05-07 20:01:0113169 StaticSocketDataProvider first_transaction(data_reads,
13170 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713171 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4513172 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613173 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4513174 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]631f1322010-04-30 17:59:1113175
bnc032658ba2016-09-26 18:17:1513176 AddSSLSocketData();
[email protected]631f1322010-04-30 17:59:1113177
Ryan Hamilton0239aac2018-05-19 00:03:1313178 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4513179 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
[email protected]631f1322010-04-30 17:59:1113180 MockWrite spdy_writes[] = {
rch8e6c6c42015-05-01 14:05:1313181 MockWrite(ASYNC, 0,
bnc8bef8da22016-05-30 01:28:2513182 "CONNECT www.example.org:443 HTTP/1.1\r\n"
13183 "Host: www.example.org:443\r\n"
rch8e6c6c42015-05-01 14:05:1313184 "Proxy-Connection: keep-alive\r\n\r\n"),
bncdf80d44fd2016-07-15 20:27:4113185 CreateMockWrite(req, 2),
[email protected]631f1322010-04-30 17:59:1113186 };
13187
[email protected]d911f1b2010-05-05 22:39:4213188 const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
13189
Raul Tambre94493c652019-03-11 17:18:3513190 spdy::SpdySerializedFrame resp(
13191 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1313192 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]631f1322010-04-30 17:59:1113193 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113194 MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(resp, 3),
13195 CreateMockRead(data, 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
[email protected]631f1322010-04-30 17:59:1113196 };
13197
Ryan Sleevib8d7ea02018-05-07 20:01:0113198 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713199 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]631f1322010-04-30 17:59:1113200
[email protected]d973e99a2012-02-17 21:02:3613201 MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
Ryan Sleevib8d7ea02018-05-07 20:01:0113202 StaticSocketDataProvider hanging_non_alternate_protocol_socket;
[email protected]2d6728692011-03-12 01:39:5513203 hanging_non_alternate_protocol_socket.set_connect_data(
13204 never_finishing_connect);
[email protected]bb88e1d32013-05-03 23:11:0713205 session_deps_.socket_factory->AddSocketDataProvider(
[email protected]2d6728692011-03-12 01:39:5513206 &hanging_non_alternate_protocol_socket);
13207
[email protected]49639fa2011-12-20 23:22:4113208 TestCompletionCallback callback;
[email protected]631f1322010-04-30 17:59:1113209
danakj1fd259a02016-04-16 03:17:0913210 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5813211 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913212 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1113213
tfarina42834112016-09-22 13:38:2013214 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
mmenkea2dcd3bf2016-08-16 21:49:4113215 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13216 EXPECT_THAT(callback.WaitForResult(), IsOk());
13217
13218 const HttpResponseInfo* response = trans->GetResponseInfo();
13219 ASSERT_TRUE(response);
13220 ASSERT_TRUE(response->headers);
13221 EXPECT_EQ("HTTP/0.9 200 OK", response->headers->GetStatusLine());
13222 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213223 EXPECT_TRUE(response->was_alpn_negotiated);
mmenkea2dcd3bf2016-08-16 21:49:4113224
13225 std::string response_data;
13226 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
13227 EXPECT_EQ("hello world", response_data);
[email protected]631f1322010-04-30 17:59:1113228
bnc87dcefc2017-05-25 12:47:5813229 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913230 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]631f1322010-04-30 17:59:1113231
tfarina42834112016-09-22 13:38:2013232 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113233 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13234 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]631f1322010-04-30 17:59:1113235
mmenkea2dcd3bf2016-08-16 21:49:4113236 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213237 ASSERT_TRUE(response);
13238 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213239 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5313240 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213241 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]631f1322010-04-30 17:59:1113242
robpercival214763f2016-07-01 23:27:0113243 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]631f1322010-04-30 17:59:1113244 EXPECT_EQ("hello!", response_data);
bncb26024382016-06-29 02:39:4513245 ASSERT_EQ(2u, capturing_proxy_resolver.resolved().size());
13246 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1313247 capturing_proxy_resolver.resolved()[0].spec());
bncce36dca22015-04-21 22:11:2313248 EXPECT_EQ("https://www.example.org/",
sammc5dd160c2015-04-02 02:43:1313249 capturing_proxy_resolver.resolved()[1].spec());
[email protected]631f1322010-04-30 17:59:1113250
[email protected]029c83b62013-01-24 05:28:2013251 LoadTimingInfo load_timing_info;
13252 EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
13253 TestLoadTimingNotReusedWithPac(load_timing_info,
13254 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]631f1322010-04-30 17:59:1113255}
[email protected]631f1322010-04-30 17:59:1113256
bncd16676a2016-07-20 16:23:0113257TEST_F(HttpNetworkTransactionTest,
bnc1c196c6e2016-05-28 13:51:4813258 UseAlternativeServiceForNpnSpdyWithExistingSpdySession) {
[email protected]2ff8b312010-04-26 22:20:5413259 HttpRequestInfo request;
13260 request.method = "GET";
bncb26024382016-06-29 02:39:4513261 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1013262 request.traffic_annotation =
13263 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]2ff8b312010-04-26 22:20:5413264
13265 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5213266 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4313267 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5213268 MockRead("\r\n"),
13269 MockRead("hello world"),
13270 MockRead(ASYNC, OK),
[email protected]2ff8b312010-04-26 22:20:5413271 };
13272
Ryan Sleevib8d7ea02018-05-07 20:01:0113273 StaticSocketDataProvider first_transaction(data_reads,
13274 base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0713275 session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
bncb26024382016-06-29 02:39:4513276 SSLSocketDataProvider ssl_http11(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3613277 ssl_http11.next_proto = kProtoHTTP11;
bncb26024382016-06-29 02:39:4513278 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11);
[email protected]2ff8b312010-04-26 22:20:5413279
bnc032658ba2016-09-26 18:17:1513280 AddSSLSocketData();
[email protected]2ff8b312010-04-26 22:20:5413281
Ryan Hamilton0239aac2018-05-19 00:03:1313282 spdy::SpdySerializedFrame req(
bncb26024382016-06-29 02:39:4513283 spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4113284 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]2ff8b312010-04-26 22:20:5413285
Raul Tambre94493c652019-03-11 17:18:3513286 spdy::SpdySerializedFrame resp(
13287 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1313288 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2ff8b312010-04-26 22:20:5413289 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4113290 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]2ff8b312010-04-26 22:20:5413291 };
13292
Ryan Sleevib8d7ea02018-05-07 20:01:0113293 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0713294 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]2ff8b312010-04-26 22:20:5413295
[email protected]83039bb2011-12-09 18:43:5513296 TestCompletionCallback callback;
[email protected]2ff8b312010-04-26 22:20:5413297
danakj1fd259a02016-04-16 03:17:0913298 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]2ff8b312010-04-26 22:20:5413299
bnc87dcefc2017-05-25 12:47:5813300 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1913301 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5413302
tfarina42834112016-09-22 13:38:2013303 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113304 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13305 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413306
13307 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213308 ASSERT_TRUE(response);
13309 ASSERT_TRUE(response->headers);
[email protected]2ff8b312010-04-26 22:20:5413310 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
13311
13312 std::string response_data;
robpercival214763f2016-07-01 23:27:0113313 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413314 EXPECT_EQ("hello world", response_data);
13315
13316 // Set up an initial SpdySession in the pool to reuse.
bnc8bef8da22016-05-30 01:28:2513317 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4013318 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1113319 PRIVACY_MODE_DISABLED,
13320 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2713321 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5213322 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]02b0c342010-09-25 21:09:3813323
bnc87dcefc2017-05-25 12:47:5813324 trans =
Jeremy Roman0579ed62017-08-29 15:56:1913325 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]2ff8b312010-04-26 22:20:5413326
tfarina42834112016-09-22 13:38:2013327 rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0113328 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13329 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413330
13331 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5213332 ASSERT_TRUE(response);
13333 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0213334 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]65041fa2010-05-21 06:56:5313335 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5213336 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]2ff8b312010-04-26 22:20:5413337
robpercival214763f2016-07-01 23:27:0113338 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]2ff8b312010-04-26 22:20:5413339 EXPECT_EQ("hello!", response_data);
[email protected]564b4912010-03-09 16:30:4213340}
13341
[email protected]044de0642010-06-17 10:42:1513342// GenerateAuthToken is a mighty big test.
13343// It tests all permutation of GenerateAuthToken behavior:
13344// - Synchronous and Asynchronous completion.
13345// - OK or error on completion.
13346// - Direct connection, non-authenticating proxy, and authenticating proxy.
13347// - HTTP or HTTPS backend (to include proxy tunneling).
13348// - Non-authenticating and authenticating backend.
13349//
[email protected]fe3b7dc2012-02-03 19:52:0913350// In all, there are 44 reasonable permuations (for example, if there are
[email protected]044de0642010-06-17 10:42:1513351// problems generating an auth token for an authenticating proxy, we don't
13352// need to test all permutations of the backend server).
13353//
13354// The test proceeds by going over each of the configuration cases, and
13355// potentially running up to three rounds in each of the tests. The TestConfig
13356// specifies both the configuration for the test as well as the expectations
13357// for the results.
bncd16676a2016-07-20 16:23:0113358TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
[email protected]0b0bf032010-09-21 18:08:5013359 static const char kServer[] = "http://www.example.com";
13360 static const char kSecureServer[] = "https://www.example.com";
13361 static const char kProxy[] = "myproxy:70";
[email protected]044de0642010-06-17 10:42:1513362
13363 enum AuthTiming {
13364 AUTH_NONE,
13365 AUTH_SYNC,
13366 AUTH_ASYNC,
13367 };
13368
13369 const MockWrite kGet(
13370 "GET / HTTP/1.1\r\n"
13371 "Host: www.example.com\r\n"
13372 "Connection: keep-alive\r\n\r\n");
13373 const MockWrite kGetProxy(
13374 "GET http://www.example.com/ HTTP/1.1\r\n"
13375 "Host: www.example.com\r\n"
13376 "Proxy-Connection: keep-alive\r\n\r\n");
13377 const MockWrite kGetAuth(
13378 "GET / HTTP/1.1\r\n"
13379 "Host: www.example.com\r\n"
13380 "Connection: keep-alive\r\n"
13381 "Authorization: auth_token\r\n\r\n");
13382 const MockWrite kGetProxyAuth(
13383 "GET http://www.example.com/ HTTP/1.1\r\n"
13384 "Host: www.example.com\r\n"
13385 "Proxy-Connection: keep-alive\r\n"
13386 "Proxy-Authorization: auth_token\r\n\r\n");
13387 const MockWrite kGetAuthThroughProxy(
13388 "GET http://www.example.com/ HTTP/1.1\r\n"
13389 "Host: www.example.com\r\n"
13390 "Proxy-Connection: keep-alive\r\n"
13391 "Authorization: auth_token\r\n\r\n");
13392 const MockWrite kGetAuthWithProxyAuth(
13393 "GET http://www.example.com/ HTTP/1.1\r\n"
13394 "Host: www.example.com\r\n"
13395 "Proxy-Connection: keep-alive\r\n"
13396 "Proxy-Authorization: auth_token\r\n"
13397 "Authorization: auth_token\r\n\r\n");
13398 const MockWrite kConnect(
13399 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1713400 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1513401 "Proxy-Connection: keep-alive\r\n\r\n");
13402 const MockWrite kConnectProxyAuth(
13403 "CONNECT www.example.com:443 HTTP/1.1\r\n"
rsleevidb16bb02015-11-12 23:47:1713404 "Host: www.example.com:443\r\n"
[email protected]044de0642010-06-17 10:42:1513405 "Proxy-Connection: keep-alive\r\n"
13406 "Proxy-Authorization: auth_token\r\n\r\n");
13407
13408 const MockRead kSuccess(
13409 "HTTP/1.1 200 OK\r\n"
13410 "Content-Type: text/html; charset=iso-8859-1\r\n"
13411 "Content-Length: 3\r\n\r\n"
13412 "Yes");
13413 const MockRead kFailure(
13414 "Should not be called.");
13415 const MockRead kServerChallenge(
13416 "HTTP/1.1 401 Unauthorized\r\n"
13417 "WWW-Authenticate: Mock realm=server\r\n"
13418 "Content-Type: text/html; charset=iso-8859-1\r\n"
13419 "Content-Length: 14\r\n\r\n"
13420 "Unauthorized\r\n");
13421 const MockRead kProxyChallenge(
13422 "HTTP/1.1 407 Unauthorized\r\n"
13423 "Proxy-Authenticate: Mock realm=proxy\r\n"
13424 "Proxy-Connection: close\r\n"
13425 "Content-Type: text/html; charset=iso-8859-1\r\n"
13426 "Content-Length: 14\r\n\r\n"
13427 "Unauthorized\r\n");
13428 const MockRead kProxyConnected(
13429 "HTTP/1.1 200 Connection Established\r\n\r\n");
13430
13431 // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
13432 // no constructors, but the C++ compiler on Windows warns about
13433 // unspecified data in compound literals. So, moved to using constructors,
13434 // and TestRound's created with the default constructor should not be used.
13435 struct TestRound {
13436 TestRound()
Raul Tambre94493c652019-03-11 17:18:3513437 : expected_rv(ERR_UNEXPECTED),
13438 extra_write(nullptr),
13439 extra_read(nullptr) {}
Raul Tambre8335a6d2019-02-21 16:57:4313440 TestRound(const MockWrite& write_arg,
13441 const MockRead& read_arg,
[email protected]044de0642010-06-17 10:42:1513442 int expected_rv_arg)
13443 : write(write_arg),
13444 read(read_arg),
13445 expected_rv(expected_rv_arg),
Raul Tambre94493c652019-03-11 17:18:3513446 extra_write(nullptr),
13447 extra_read(nullptr) {}
[email protected]044de0642010-06-17 10:42:1513448 TestRound(const MockWrite& write_arg, const MockRead& read_arg,
13449 int expected_rv_arg, const MockWrite* extra_write_arg,
[email protected]f871ee152012-07-27 19:02:0113450 const MockRead* extra_read_arg)
[email protected]044de0642010-06-17 10:42:1513451 : write(write_arg),
13452 read(read_arg),
13453 expected_rv(expected_rv_arg),
13454 extra_write(extra_write_arg),
13455 extra_read(extra_read_arg) {
13456 }
13457 MockWrite write;
13458 MockRead read;
13459 int expected_rv;
13460 const MockWrite* extra_write;
13461 const MockRead* extra_read;
13462 };
13463
13464 static const int kNoSSL = 500;
13465
13466 struct TestConfig {
asanka463ca4262016-11-16 02:34:3113467 int line_number;
thestig9d3bb0c2015-01-24 00:49:5113468 const char* const proxy_url;
[email protected]044de0642010-06-17 10:42:1513469 AuthTiming proxy_auth_timing;
asanka463ca4262016-11-16 02:34:3113470 int first_generate_proxy_token_rv;
thestig9d3bb0c2015-01-24 00:49:5113471 const char* const server_url;
[email protected]044de0642010-06-17 10:42:1513472 AuthTiming server_auth_timing;
asanka463ca4262016-11-16 02:34:3113473 int first_generate_server_token_rv;
[email protected]044de0642010-06-17 10:42:1513474 int num_auth_rounds;
13475 int first_ssl_round;
asankae2257db2016-10-11 22:03:1613476 TestRound rounds[4];
[email protected]044de0642010-06-17 10:42:1513477 } test_configs[] = {
asankac93076192016-10-03 15:46:0213478 // Non-authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3113479 {__LINE__,
13480 nullptr,
asankac93076192016-10-03 15:46:0213481 AUTH_NONE,
13482 OK,
13483 kServer,
13484 AUTH_NONE,
13485 OK,
13486 1,
13487 kNoSSL,
13488 {TestRound(kGet, kSuccess, OK)}},
13489 // Authenticating HTTP server with a direct connection.
asanka463ca4262016-11-16 02:34:3113490 {__LINE__,
13491 nullptr,
asankac93076192016-10-03 15:46:0213492 AUTH_NONE,
13493 OK,
13494 kServer,
13495 AUTH_SYNC,
13496 OK,
13497 2,
13498 kNoSSL,
13499 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513500 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113501 {__LINE__,
13502 nullptr,
asankac93076192016-10-03 15:46:0213503 AUTH_NONE,
13504 OK,
13505 kServer,
13506 AUTH_SYNC,
13507 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613508 3,
13509 kNoSSL,
13510 {TestRound(kGet, kServerChallenge, OK),
13511 TestRound(kGet, kServerChallenge, OK),
13512 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113513 {__LINE__,
13514 nullptr,
asankae2257db2016-10-11 22:03:1613515 AUTH_NONE,
13516 OK,
13517 kServer,
13518 AUTH_SYNC,
13519 ERR_UNSUPPORTED_AUTH_SCHEME,
13520 2,
13521 kNoSSL,
13522 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113523 {__LINE__,
13524 nullptr,
asankae2257db2016-10-11 22:03:1613525 AUTH_NONE,
13526 OK,
13527 kServer,
13528 AUTH_SYNC,
13529 ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
13530 2,
13531 kNoSSL,
13532 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113533 {__LINE__,
13534 kProxy,
asankae2257db2016-10-11 22:03:1613535 AUTH_SYNC,
13536 ERR_FAILED,
13537 kServer,
13538 AUTH_NONE,
13539 OK,
13540 2,
13541 kNoSSL,
13542 {TestRound(kGetProxy, kProxyChallenge, OK),
13543 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113544 {__LINE__,
13545 kProxy,
asankae2257db2016-10-11 22:03:1613546 AUTH_ASYNC,
13547 ERR_FAILED,
13548 kServer,
13549 AUTH_NONE,
13550 OK,
13551 2,
13552 kNoSSL,
13553 {TestRound(kGetProxy, kProxyChallenge, OK),
13554 TestRound(kGetProxy, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113555 {__LINE__,
13556 nullptr,
asankae2257db2016-10-11 22:03:1613557 AUTH_NONE,
13558 OK,
13559 kServer,
13560 AUTH_SYNC,
13561 ERR_FAILED,
asankac93076192016-10-03 15:46:0213562 2,
13563 kNoSSL,
13564 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613565 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113566 {__LINE__,
13567 nullptr,
asankae2257db2016-10-11 22:03:1613568 AUTH_NONE,
13569 OK,
13570 kServer,
13571 AUTH_ASYNC,
13572 ERR_FAILED,
13573 2,
13574 kNoSSL,
13575 {TestRound(kGet, kServerChallenge, OK),
13576 TestRound(kGet, kFailure, ERR_FAILED)}},
asanka463ca4262016-11-16 02:34:3113577 {__LINE__,
13578 nullptr,
asankac93076192016-10-03 15:46:0213579 AUTH_NONE,
13580 OK,
13581 kServer,
13582 AUTH_ASYNC,
13583 OK,
13584 2,
13585 kNoSSL,
13586 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513587 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113588 {__LINE__,
13589 nullptr,
asankac93076192016-10-03 15:46:0213590 AUTH_NONE,
13591 OK,
13592 kServer,
13593 AUTH_ASYNC,
13594 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613595 3,
asankac93076192016-10-03 15:46:0213596 kNoSSL,
13597 {TestRound(kGet, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613598 // The second round uses a HttpAuthHandlerMock that always succeeds.
13599 TestRound(kGet, kServerChallenge, OK),
13600 TestRound(kGetAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213601 // Non-authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113602 {__LINE__,
13603 kProxy,
asankac93076192016-10-03 15:46:0213604 AUTH_NONE,
13605 OK,
13606 kServer,
13607 AUTH_NONE,
13608 OK,
13609 1,
13610 kNoSSL,
13611 {TestRound(kGetProxy, kSuccess, OK)}},
13612 // Authenticating HTTP server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113613 {__LINE__,
13614 kProxy,
asankac93076192016-10-03 15:46:0213615 AUTH_NONE,
13616 OK,
13617 kServer,
13618 AUTH_SYNC,
13619 OK,
13620 2,
13621 kNoSSL,
13622 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513623 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113624 {__LINE__,
13625 kProxy,
asankac93076192016-10-03 15:46:0213626 AUTH_NONE,
13627 OK,
13628 kServer,
13629 AUTH_SYNC,
13630 ERR_INVALID_AUTH_CREDENTIALS,
asankae2257db2016-10-11 22:03:1613631 3,
asankac93076192016-10-03 15:46:0213632 kNoSSL,
13633 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613634 TestRound(kGetProxy, kServerChallenge, OK),
13635 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113636 {__LINE__,
13637 kProxy,
asankac93076192016-10-03 15:46:0213638 AUTH_NONE,
13639 OK,
13640 kServer,
13641 AUTH_ASYNC,
13642 OK,
13643 2,
13644 kNoSSL,
13645 {TestRound(kGetProxy, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513646 TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113647 {__LINE__,
13648 kProxy,
asankac93076192016-10-03 15:46:0213649 AUTH_NONE,
13650 OK,
13651 kServer,
13652 AUTH_ASYNC,
13653 ERR_INVALID_AUTH_CREDENTIALS,
13654 2,
13655 kNoSSL,
13656 {TestRound(kGetProxy, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613657 TestRound(kGetProxy, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213658 // Non-authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113659 {__LINE__,
13660 kProxy,
asankac93076192016-10-03 15:46:0213661 AUTH_SYNC,
13662 OK,
13663 kServer,
13664 AUTH_NONE,
13665 OK,
13666 2,
13667 kNoSSL,
13668 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513669 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113670 {__LINE__,
13671 kProxy,
asankac93076192016-10-03 15:46:0213672 AUTH_SYNC,
13673 ERR_INVALID_AUTH_CREDENTIALS,
13674 kServer,
13675 AUTH_NONE,
13676 OK,
13677 2,
13678 kNoSSL,
13679 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613680 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113681 {__LINE__,
13682 kProxy,
asankac93076192016-10-03 15:46:0213683 AUTH_ASYNC,
13684 OK,
13685 kServer,
13686 AUTH_NONE,
13687 OK,
13688 2,
13689 kNoSSL,
13690 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513691 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113692 {__LINE__,
13693 kProxy,
asankac93076192016-10-03 15:46:0213694 AUTH_ASYNC,
13695 ERR_INVALID_AUTH_CREDENTIALS,
13696 kServer,
13697 AUTH_NONE,
13698 OK,
13699 2,
13700 kNoSSL,
13701 {TestRound(kGetProxy, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613702 TestRound(kGetProxy, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113703 {__LINE__,
13704 kProxy,
13705 AUTH_ASYNC,
13706 ERR_INVALID_AUTH_CREDENTIALS,
13707 kServer,
13708 AUTH_NONE,
13709 OK,
13710 3,
13711 kNoSSL,
13712 {TestRound(kGetProxy, kProxyChallenge, OK),
13713 TestRound(kGetProxy, kProxyChallenge, OK),
13714 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213715 // Authenticating HTTP server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113716 {__LINE__,
13717 kProxy,
asankac93076192016-10-03 15:46:0213718 AUTH_SYNC,
13719 OK,
13720 kServer,
13721 AUTH_SYNC,
13722 OK,
13723 3,
13724 kNoSSL,
13725 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513726 TestRound(kGetProxyAuth, kServerChallenge, OK),
13727 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113728 {__LINE__,
13729 kProxy,
asankac93076192016-10-03 15:46:0213730 AUTH_SYNC,
13731 OK,
13732 kServer,
13733 AUTH_SYNC,
13734 ERR_INVALID_AUTH_CREDENTIALS,
13735 3,
13736 kNoSSL,
13737 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513738 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613739 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113740 {__LINE__,
13741 kProxy,
asankac93076192016-10-03 15:46:0213742 AUTH_ASYNC,
13743 OK,
13744 kServer,
13745 AUTH_SYNC,
13746 OK,
13747 3,
13748 kNoSSL,
13749 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513750 TestRound(kGetProxyAuth, kServerChallenge, OK),
13751 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113752 {__LINE__,
13753 kProxy,
asankac93076192016-10-03 15:46:0213754 AUTH_ASYNC,
13755 OK,
13756 kServer,
13757 AUTH_SYNC,
13758 ERR_INVALID_AUTH_CREDENTIALS,
13759 3,
13760 kNoSSL,
13761 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513762 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613763 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113764 {__LINE__,
13765 kProxy,
asankac93076192016-10-03 15:46:0213766 AUTH_SYNC,
13767 OK,
13768 kServer,
13769 AUTH_ASYNC,
13770 OK,
13771 3,
13772 kNoSSL,
13773 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513774 TestRound(kGetProxyAuth, kServerChallenge, OK),
13775 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113776 {__LINE__,
13777 kProxy,
13778 AUTH_SYNC,
13779 ERR_INVALID_AUTH_CREDENTIALS,
13780 kServer,
13781 AUTH_ASYNC,
13782 OK,
13783 4,
13784 kNoSSL,
13785 {TestRound(kGetProxy, kProxyChallenge, OK),
13786 TestRound(kGetProxy, kProxyChallenge, OK),
13787 TestRound(kGetProxyAuth, kServerChallenge, OK),
13788 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
13789 {__LINE__,
13790 kProxy,
asankac93076192016-10-03 15:46:0213791 AUTH_SYNC,
13792 OK,
13793 kServer,
13794 AUTH_ASYNC,
13795 ERR_INVALID_AUTH_CREDENTIALS,
13796 3,
13797 kNoSSL,
13798 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513799 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613800 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113801 {__LINE__,
13802 kProxy,
asankac93076192016-10-03 15:46:0213803 AUTH_ASYNC,
13804 OK,
13805 kServer,
13806 AUTH_ASYNC,
13807 OK,
13808 3,
13809 kNoSSL,
13810 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513811 TestRound(kGetProxyAuth, kServerChallenge, OK),
13812 TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113813 {__LINE__,
13814 kProxy,
asankac93076192016-10-03 15:46:0213815 AUTH_ASYNC,
13816 OK,
13817 kServer,
13818 AUTH_ASYNC,
13819 ERR_INVALID_AUTH_CREDENTIALS,
13820 3,
13821 kNoSSL,
13822 {TestRound(kGetProxy, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513823 TestRound(kGetProxyAuth, kServerChallenge, OK),
asankae2257db2016-10-11 22:03:1613824 TestRound(kGetProxyAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113825 {__LINE__,
13826 kProxy,
13827 AUTH_ASYNC,
13828 ERR_INVALID_AUTH_CREDENTIALS,
13829 kServer,
13830 AUTH_ASYNC,
13831 ERR_INVALID_AUTH_CREDENTIALS,
13832 4,
13833 kNoSSL,
13834 {TestRound(kGetProxy, kProxyChallenge, OK),
13835 TestRound(kGetProxy, kProxyChallenge, OK),
13836 TestRound(kGetProxyAuth, kServerChallenge, OK),
13837 TestRound(kGetProxyAuth, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213838 // Non-authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113839 {__LINE__,
13840 nullptr,
asankac93076192016-10-03 15:46:0213841 AUTH_NONE,
13842 OK,
13843 kSecureServer,
13844 AUTH_NONE,
13845 OK,
13846 1,
13847 0,
13848 {TestRound(kGet, kSuccess, OK)}},
13849 // Authenticating HTTPS server with a direct connection.
asanka463ca4262016-11-16 02:34:3113850 {__LINE__,
13851 nullptr,
asankac93076192016-10-03 15:46:0213852 AUTH_NONE,
13853 OK,
13854 kSecureServer,
13855 AUTH_SYNC,
13856 OK,
13857 2,
13858 0,
13859 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513860 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113861 {__LINE__,
13862 nullptr,
asankac93076192016-10-03 15:46:0213863 AUTH_NONE,
13864 OK,
13865 kSecureServer,
13866 AUTH_SYNC,
13867 ERR_INVALID_AUTH_CREDENTIALS,
13868 2,
13869 0,
asankae2257db2016-10-11 22:03:1613870 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113871 {__LINE__,
13872 nullptr,
asankac93076192016-10-03 15:46:0213873 AUTH_NONE,
13874 OK,
13875 kSecureServer,
13876 AUTH_ASYNC,
13877 OK,
13878 2,
13879 0,
13880 {TestRound(kGet, kServerChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513881 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113882 {__LINE__,
13883 nullptr,
asankac93076192016-10-03 15:46:0213884 AUTH_NONE,
13885 OK,
13886 kSecureServer,
13887 AUTH_ASYNC,
13888 ERR_INVALID_AUTH_CREDENTIALS,
13889 2,
13890 0,
asankae2257db2016-10-11 22:03:1613891 {TestRound(kGet, kServerChallenge, OK), TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213892 // Non-authenticating HTTPS server with a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113893 {__LINE__,
13894 kProxy,
asankac93076192016-10-03 15:46:0213895 AUTH_NONE,
13896 OK,
13897 kSecureServer,
13898 AUTH_NONE,
13899 OK,
13900 1,
13901 0,
13902 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
13903 // Authenticating HTTPS server through a non-authenticating proxy.
asanka463ca4262016-11-16 02:34:3113904 {__LINE__,
13905 kProxy,
asankac93076192016-10-03 15:46:0213906 AUTH_NONE,
13907 OK,
13908 kSecureServer,
13909 AUTH_SYNC,
13910 OK,
13911 2,
13912 0,
13913 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513914 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113915 {__LINE__,
13916 kProxy,
asankac93076192016-10-03 15:46:0213917 AUTH_NONE,
13918 OK,
13919 kSecureServer,
13920 AUTH_SYNC,
13921 ERR_INVALID_AUTH_CREDENTIALS,
13922 2,
13923 0,
13924 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613925 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113926 {__LINE__,
13927 kProxy,
asankac93076192016-10-03 15:46:0213928 AUTH_NONE,
13929 OK,
13930 kSecureServer,
13931 AUTH_ASYNC,
13932 OK,
13933 2,
13934 0,
13935 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1513936 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3113937 {__LINE__,
13938 kProxy,
asankac93076192016-10-03 15:46:0213939 AUTH_NONE,
13940 OK,
13941 kSecureServer,
13942 AUTH_ASYNC,
13943 ERR_INVALID_AUTH_CREDENTIALS,
13944 2,
13945 0,
13946 {TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
asankae2257db2016-10-11 22:03:1613947 TestRound(kGet, kSuccess, OK)}},
asankac93076192016-10-03 15:46:0213948 // Non-Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3113949 {__LINE__,
13950 kProxy,
asankac93076192016-10-03 15:46:0213951 AUTH_SYNC,
13952 OK,
13953 kSecureServer,
13954 AUTH_NONE,
13955 OK,
13956 2,
13957 1,
13958 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1513959 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113960 {__LINE__,
13961 kProxy,
asankac93076192016-10-03 15:46:0213962 AUTH_SYNC,
13963 ERR_INVALID_AUTH_CREDENTIALS,
13964 kSecureServer,
13965 AUTH_NONE,
13966 OK,
13967 2,
13968 kNoSSL,
13969 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1613970 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113971 {__LINE__,
13972 kProxy,
asankae2257db2016-10-11 22:03:1613973 AUTH_SYNC,
13974 ERR_UNSUPPORTED_AUTH_SCHEME,
13975 kSecureServer,
13976 AUTH_NONE,
13977 OK,
13978 2,
13979 kNoSSL,
13980 {TestRound(kConnect, kProxyChallenge, OK),
13981 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3113982 {__LINE__,
13983 kProxy,
asankae2257db2016-10-11 22:03:1613984 AUTH_SYNC,
13985 ERR_UNEXPECTED,
13986 kSecureServer,
13987 AUTH_NONE,
13988 OK,
13989 2,
13990 kNoSSL,
13991 {TestRound(kConnect, kProxyChallenge, OK),
13992 TestRound(kConnect, kProxyConnected, ERR_UNEXPECTED)}},
asanka463ca4262016-11-16 02:34:3113993 {__LINE__,
13994 kProxy,
asankac93076192016-10-03 15:46:0213995 AUTH_ASYNC,
13996 OK,
13997 kSecureServer,
13998 AUTH_NONE,
13999 OK,
14000 2,
14001 1,
14002 {TestRound(kConnect, kProxyChallenge, OK),
[email protected]044de0642010-06-17 10:42:1514003 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
asanka463ca4262016-11-16 02:34:3114004 {__LINE__,
14005 kProxy,
asankac93076192016-10-03 15:46:0214006 AUTH_ASYNC,
14007 ERR_INVALID_AUTH_CREDENTIALS,
14008 kSecureServer,
14009 AUTH_NONE,
14010 OK,
14011 2,
14012 kNoSSL,
14013 {TestRound(kConnect, kProxyChallenge, OK),
asankae2257db2016-10-11 22:03:1614014 TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
asankac93076192016-10-03 15:46:0214015 // Authenticating HTTPS server through an authenticating proxy.
asanka463ca4262016-11-16 02:34:3114016 {__LINE__,
14017 kProxy,
asankac93076192016-10-03 15:46:0214018 AUTH_SYNC,
14019 OK,
14020 kSecureServer,
14021 AUTH_SYNC,
14022 OK,
14023 3,
14024 1,
14025 {TestRound(kConnect, kProxyChallenge, OK),
14026 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14027 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514028 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114029 {__LINE__,
14030 kProxy,
asankac93076192016-10-03 15:46:0214031 AUTH_SYNC,
14032 OK,
14033 kSecureServer,
14034 AUTH_SYNC,
14035 ERR_INVALID_AUTH_CREDENTIALS,
14036 3,
14037 1,
14038 {TestRound(kConnect, kProxyChallenge, OK),
14039 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14040 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614041 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114042 {__LINE__,
14043 kProxy,
asankac93076192016-10-03 15:46:0214044 AUTH_ASYNC,
14045 OK,
14046 kSecureServer,
14047 AUTH_SYNC,
14048 OK,
14049 3,
14050 1,
14051 {TestRound(kConnect, kProxyChallenge, OK),
14052 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14053 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514054 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114055 {__LINE__,
14056 kProxy,
asankac93076192016-10-03 15:46:0214057 AUTH_ASYNC,
14058 OK,
14059 kSecureServer,
14060 AUTH_SYNC,
14061 ERR_INVALID_AUTH_CREDENTIALS,
14062 3,
14063 1,
14064 {TestRound(kConnect, kProxyChallenge, OK),
14065 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14066 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614067 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114068 {__LINE__,
14069 kProxy,
asankac93076192016-10-03 15:46:0214070 AUTH_SYNC,
14071 OK,
14072 kSecureServer,
14073 AUTH_ASYNC,
14074 OK,
14075 3,
14076 1,
14077 {TestRound(kConnect, kProxyChallenge, OK),
14078 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14079 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514080 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114081 {__LINE__,
14082 kProxy,
asankac93076192016-10-03 15:46:0214083 AUTH_SYNC,
14084 OK,
14085 kSecureServer,
14086 AUTH_ASYNC,
14087 ERR_INVALID_AUTH_CREDENTIALS,
14088 3,
14089 1,
14090 {TestRound(kConnect, kProxyChallenge, OK),
14091 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14092 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614093 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114094 {__LINE__,
14095 kProxy,
asankac93076192016-10-03 15:46:0214096 AUTH_ASYNC,
14097 OK,
14098 kSecureServer,
14099 AUTH_ASYNC,
14100 OK,
14101 3,
14102 1,
14103 {TestRound(kConnect, kProxyChallenge, OK),
14104 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14105 &kServerChallenge),
[email protected]044de0642010-06-17 10:42:1514106 TestRound(kGetAuth, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114107 {__LINE__,
14108 kProxy,
asankac93076192016-10-03 15:46:0214109 AUTH_ASYNC,
14110 OK,
14111 kSecureServer,
14112 AUTH_ASYNC,
14113 ERR_INVALID_AUTH_CREDENTIALS,
14114 3,
14115 1,
14116 {TestRound(kConnect, kProxyChallenge, OK),
14117 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14118 &kServerChallenge),
asankae2257db2016-10-11 22:03:1614119 TestRound(kGet, kSuccess, OK)}},
asanka463ca4262016-11-16 02:34:3114120 {__LINE__,
14121 kProxy,
14122 AUTH_ASYNC,
14123 ERR_INVALID_AUTH_CREDENTIALS,
14124 kSecureServer,
14125 AUTH_ASYNC,
14126 ERR_INVALID_AUTH_CREDENTIALS,
14127 4,
14128 2,
14129 {TestRound(kConnect, kProxyChallenge, OK),
14130 TestRound(kConnect, kProxyChallenge, OK),
14131 TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet,
14132 &kServerChallenge),
14133 TestRound(kGet, kSuccess, OK)}},
[email protected]044de0642010-06-17 10:42:1514134 };
14135
asanka463ca4262016-11-16 02:34:3114136 for (const auto& test_config : test_configs) {
14137 SCOPED_TRACE(::testing::Message() << "Test config at "
14138 << test_config.line_number);
[email protected]2d01c262011-08-11 23:07:0814139 HttpAuthHandlerMock::Factory* auth_factory(
14140 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0714141 session_deps_.http_auth_handler_factory.reset(auth_factory);
asanka5ffd5d72016-03-23 16:20:4914142 SSLInfo empty_ssl_info;
[email protected]65d34382010-07-01 18:12:2614143
14144 // Set up authentication handlers as necessary.
[email protected]044de0642010-06-17 10:42:1514145 if (test_config.proxy_auth_timing != AUTH_NONE) {
asanka463ca4262016-11-16 02:34:3114146 for (int n = 0; n < 3; n++) {
[email protected]2d01c262011-08-11 23:07:0814147 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
14148 std::string auth_challenge = "Mock realm=proxy";
14149 GURL origin(test_config.proxy_url);
[email protected]df41d0d82014-03-13 00:43:2414150 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14151 auth_challenge.end());
[email protected]2d01c262011-08-11 23:07:0814152 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
tfarina42834112016-09-22 13:38:2014153 empty_ssl_info, origin,
14154 NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0814155 auth_handler->SetGenerateExpectation(
14156 test_config.proxy_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3114157 n == 0 ? test_config.first_generate_proxy_token_rv : OK);
[email protected]2d01c262011-08-11 23:07:0814158 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
14159 }
[email protected]044de0642010-06-17 10:42:1514160 }
14161 if (test_config.server_auth_timing != AUTH_NONE) {
[email protected]3fd9dae2010-06-21 11:39:0014162 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
[email protected]044de0642010-06-17 10:42:1514163 std::string auth_challenge = "Mock realm=server";
14164 GURL origin(test_config.server_url);
[email protected]df41d0d82014-03-13 00:43:2414165 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14166 auth_challenge.end());
[email protected]044de0642010-06-17 10:42:1514167 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2014168 empty_ssl_info, origin,
14169 NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1514170 auth_handler->SetGenerateExpectation(
14171 test_config.server_auth_timing == AUTH_ASYNC,
asanka463ca4262016-11-16 02:34:3114172 test_config.first_generate_server_token_rv);
[email protected]2d01c262011-08-11 23:07:0814173 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
asankae2257db2016-10-11 22:03:1614174
14175 // The second handler always succeeds. It should only be used where there
14176 // are multiple auth sessions for server auth in the same network
14177 // transaction using the same auth scheme.
14178 std::unique_ptr<HttpAuthHandlerMock> second_handler =
Jeremy Roman0579ed62017-08-29 15:56:1914179 std::make_unique<HttpAuthHandlerMock>();
asankae2257db2016-10-11 22:03:1614180 second_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
14181 empty_ssl_info, origin,
14182 NetLogWithSource());
14183 second_handler->SetGenerateExpectation(true, OK);
14184 auth_factory->AddMockHandler(second_handler.release(),
14185 HttpAuth::AUTH_SERVER);
[email protected]044de0642010-06-17 10:42:1514186 }
14187 if (test_config.proxy_url) {
Lily Houghton8c2f97d2018-01-22 05:06:5914188 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914189 ProxyResolutionService::CreateFixed(test_config.proxy_url,
14190 TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1514191 } else {
Bence Béky53a5aef2018-03-29 21:54:1214192 session_deps_.proxy_resolution_service =
14193 ProxyResolutionService::CreateDirect();
[email protected]044de0642010-06-17 10:42:1514194 }
14195
14196 HttpRequestInfo request;
14197 request.method = "GET";
14198 request.url = GURL(test_config.server_url);
Ramin Halavatib5e433e62018-02-07 07:41:1014199 request.traffic_annotation =
14200 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]044de0642010-06-17 10:42:1514201
danakj1fd259a02016-04-16 03:17:0914202 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]044de0642010-06-17 10:42:1514203
rchcb68dc62015-05-21 04:45:3614204 SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
14205
14206 std::vector<std::vector<MockRead>> mock_reads(1);
14207 std::vector<std::vector<MockWrite>> mock_writes(1);
[email protected]044de0642010-06-17 10:42:1514208 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2214209 SCOPED_TRACE(round);
[email protected]044de0642010-06-17 10:42:1514210 const TestRound& read_write_round = test_config.rounds[round];
14211
14212 // Set up expected reads and writes.
rchcb68dc62015-05-21 04:45:3614213 mock_reads.back().push_back(read_write_round.read);
14214 mock_writes.back().push_back(read_write_round.write);
14215
14216 // kProxyChallenge uses Proxy-Connection: close which means that the
14217 // socket is closed and a new one will be created for the next request.
mmenkee71e15332015-10-07 16:39:5414218 if (read_write_round.read.data == kProxyChallenge.data) {
rchcb68dc62015-05-21 04:45:3614219 mock_reads.push_back(std::vector<MockRead>());
14220 mock_writes.push_back(std::vector<MockWrite>());
[email protected]044de0642010-06-17 10:42:1514221 }
14222
rchcb68dc62015-05-21 04:45:3614223 if (read_write_round.extra_read) {
14224 mock_reads.back().push_back(*read_write_round.extra_read);
[email protected]044de0642010-06-17 10:42:1514225 }
rchcb68dc62015-05-21 04:45:3614226 if (read_write_round.extra_write) {
14227 mock_writes.back().push_back(*read_write_round.extra_write);
14228 }
[email protected]044de0642010-06-17 10:42:1514229
14230 // Add an SSL sequence if necessary.
[email protected]044de0642010-06-17 10:42:1514231 if (round >= test_config.first_ssl_round)
[email protected]bb88e1d32013-05-03 23:11:0714232 session_deps_.socket_factory->AddSSLSocketDataProvider(
[email protected]044de0642010-06-17 10:42:1514233 &ssl_socket_data_provider);
rchcb68dc62015-05-21 04:45:3614234 }
[email protected]044de0642010-06-17 10:42:1514235
danakj1fd259a02016-04-16 03:17:0914236 std::vector<std::unique_ptr<StaticSocketDataProvider>> data_providers;
rchcb68dc62015-05-21 04:45:3614237 for (size_t i = 0; i < mock_reads.size(); ++i) {
Jeremy Roman0579ed62017-08-29 15:56:1914238 data_providers.push_back(std::make_unique<StaticSocketDataProvider>(
Ryan Sleevib8d7ea02018-05-07 20:01:0114239 mock_reads[i], mock_writes[i]));
rchcb68dc62015-05-21 04:45:3614240 session_deps_.socket_factory->AddSocketDataProvider(
olli.raula525048c2015-12-10 07:38:3214241 data_providers.back().get());
rchcb68dc62015-05-21 04:45:3614242 }
14243
mmenkecc2298e2015-12-07 18:20:1814244 // Transaction must be created after DataProviders, so it's destroyed before
14245 // they are as well.
14246 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
14247
rchcb68dc62015-05-21 04:45:3614248 for (int round = 0; round < test_config.num_auth_rounds; ++round) {
davidben8c7089a2017-04-17 20:38:2214249 SCOPED_TRACE(round);
rchcb68dc62015-05-21 04:45:3614250 const TestRound& read_write_round = test_config.rounds[round];
[email protected]044de0642010-06-17 10:42:1514251 // Start or restart the transaction.
[email protected]49639fa2011-12-20 23:22:4114252 TestCompletionCallback callback;
[email protected]044de0642010-06-17 10:42:1514253 int rv;
14254 if (round == 0) {
tfarina42834112016-09-22 13:38:2014255 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]044de0642010-06-17 10:42:1514256 } else {
[email protected]49639fa2011-12-20 23:22:4114257 rv = trans.RestartWithAuth(
14258 AuthCredentials(kFoo, kBar), callback.callback());
[email protected]044de0642010-06-17 10:42:1514259 }
14260 if (rv == ERR_IO_PENDING)
14261 rv = callback.WaitForResult();
14262
14263 // Compare results with expected data.
asankae2257db2016-10-11 22:03:1614264 EXPECT_THAT(rv, IsError(read_write_round.expected_rv));
[email protected]0b0bf032010-09-21 18:08:5014265 const HttpResponseInfo* response = trans.GetResponseInfo();
ttuttlec0c828492015-05-15 01:25:5514266 if (read_write_round.expected_rv != OK) {
[email protected]044de0642010-06-17 10:42:1514267 EXPECT_EQ(round + 1, test_config.num_auth_rounds);
14268 continue;
14269 }
14270 if (round + 1 < test_config.num_auth_rounds) {
Emily Starkf2c9bbd2019-04-09 17:08:5814271 EXPECT_TRUE(response->auth_challenge.has_value());
[email protected]044de0642010-06-17 10:42:1514272 } else {
Emily Starkf2c9bbd2019-04-09 17:08:5814273 EXPECT_FALSE(response->auth_challenge.has_value());
asankae2257db2016-10-11 22:03:1614274 EXPECT_FALSE(trans.IsReadyToRestartForAuth());
[email protected]044de0642010-06-17 10:42:1514275 }
14276 }
[email protected]e5ae96a2010-04-14 20:12:4514277 }
14278}
14279
bncd16676a2016-07-20 16:23:0114280TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
[email protected]c871bce92010-07-15 21:51:1414281 // Do multi-round authentication and make sure it works correctly.
[email protected]c871bce92010-07-15 21:51:1414282 HttpAuthHandlerMock::Factory* auth_factory(
14283 new HttpAuthHandlerMock::Factory());
[email protected]bb88e1d32013-05-03 23:11:0714284 session_deps_.http_auth_handler_factory.reset(auth_factory);
Bence Béky53a5aef2018-03-29 21:54:1214285 session_deps_.proxy_resolution_service =
14286 ProxyResolutionService::CreateDirect();
[email protected]bb88e1d32013-05-03 23:11:0714287 session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
[email protected]c871bce92010-07-15 21:51:1414288
14289 HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
14290 auth_handler->set_connection_based(true);
14291 std::string auth_challenge = "Mock realm=server";
14292 GURL origin("http://www.example.com");
[email protected]df41d0d82014-03-13 00:43:2414293 HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
14294 auth_challenge.end());
asanka5ffd5d72016-03-23 16:20:4914295 SSLInfo empty_ssl_info;
[email protected]c871bce92010-07-15 21:51:1414296 auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
tfarina42834112016-09-22 13:38:2014297 empty_ssl_info, origin, NetLogWithSource());
[email protected]2d01c262011-08-11 23:07:0814298 auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
[email protected]c871bce92010-07-15 21:51:1414299
[email protected]c871bce92010-07-15 21:51:1414300 int rv = OK;
Raul Tambre94493c652019-03-11 17:18:3514301 const HttpResponseInfo* response = nullptr;
[email protected]c871bce92010-07-15 21:51:1414302 HttpRequestInfo request;
14303 request.method = "GET";
14304 request.url = origin;
Ramin Halavatib5e433e62018-02-07 07:41:1014305 request.traffic_annotation =
14306 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2714307
danakj1fd259a02016-04-16 03:17:0914308 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]7ef4cbbb2011-02-06 11:19:1014309
14310 // Use a TCP Socket Pool with only one connection per group. This is used
14311 // to validate that the TCP socket is not released to the pool between
14312 // each round of multi-round authentication.
mmenkee65e7af2015-10-13 17:16:4214313 HttpNetworkSessionPeer session_peer(session.get());
Matt Menked6fd2a52019-03-20 06:14:3614314 CommonConnectJobParams common_connect_job_params(
14315 session->CreateCommonConnectJobParams());
[email protected]ab739042011-04-07 15:22:2814316 TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
Tarun Bansala7635092019-02-20 10:00:5914317 50, // Max sockets for pool
14318 1, // Max sockets per group
14319 base::TimeDelta::FromSeconds(10), // unused_idle_socket_timeout
Matt Menkeaafff542019-04-22 22:09:3614320 ProxyServer::Direct(), false, // is_for_websockets
Matt Menked6fd2a52019-03-20 06:14:3614321 &common_connect_job_params, session_deps_.ssl_config_service.get());
Jeremy Roman0579ed62017-08-29 15:56:1914322 auto mock_pool_manager = std::make_unique<MockClientSocketPoolManager>();
Matt Menked23ab952019-03-06 00:24:4014323 mock_pool_manager->SetSocketPool(ProxyServer::Direct(),
14324 base::WrapUnique(transport_pool));
dchengc7eeda422015-12-26 03:56:4814325 session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager));
[email protected]7ef4cbbb2011-02-06 11:19:1014326
bnc691fda62016-08-12 00:43:1614327 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114328 TestCompletionCallback callback;
[email protected]c871bce92010-07-15 21:51:1414329
14330 const MockWrite kGet(
14331 "GET / HTTP/1.1\r\n"
14332 "Host: www.example.com\r\n"
14333 "Connection: keep-alive\r\n\r\n");
14334 const MockWrite kGetAuth(
14335 "GET / HTTP/1.1\r\n"
14336 "Host: www.example.com\r\n"
14337 "Connection: keep-alive\r\n"
14338 "Authorization: auth_token\r\n\r\n");
14339
14340 const MockRead kServerChallenge(
14341 "HTTP/1.1 401 Unauthorized\r\n"
14342 "WWW-Authenticate: Mock realm=server\r\n"
14343 "Content-Type: text/html; charset=iso-8859-1\r\n"
14344 "Content-Length: 14\r\n\r\n"
14345 "Unauthorized\r\n");
14346 const MockRead kSuccess(
14347 "HTTP/1.1 200 OK\r\n"
14348 "Content-Type: text/html; charset=iso-8859-1\r\n"
14349 "Content-Length: 3\r\n\r\n"
14350 "Yes");
14351
14352 MockWrite writes[] = {
14353 // First round
14354 kGet,
14355 // Second round
14356 kGetAuth,
14357 // Third round
14358 kGetAuth,
[email protected]eca50e122010-09-11 14:03:3014359 // Fourth round
[email protected]7ef4cbbb2011-02-06 11:19:1014360 kGetAuth,
14361 // Competing request
14362 kGet,
[email protected]c871bce92010-07-15 21:51:1414363 };
14364 MockRead reads[] = {
14365 // First round
14366 kServerChallenge,
14367 // Second round
14368 kServerChallenge,
14369 // Third round
[email protected]eca50e122010-09-11 14:03:3014370 kServerChallenge,
14371 // Fourth round
[email protected]c871bce92010-07-15 21:51:1414372 kSuccess,
[email protected]7ef4cbbb2011-02-06 11:19:1014373 // Competing response
14374 kSuccess,
[email protected]c871bce92010-07-15 21:51:1414375 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114376 StaticSocketDataProvider data_provider(reads, writes);
[email protected]bb88e1d32013-05-03 23:11:0714377 session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
[email protected]c871bce92010-07-15 21:51:1414378
Matt Menkef6edce752019-03-19 17:21:5614379 const ClientSocketPool::GroupId kSocketGroup(
14380 HostPortPair("www.example.com", 80), ClientSocketPool::SocketType::kHttp,
Matt Menkebdf777802019-04-22 19:38:5914381 PrivacyMode::PRIVACY_MODE_DISABLED);
[email protected]7ef4cbbb2011-02-06 11:19:1014382
14383 // First round of authentication.
[email protected]c871bce92010-07-15 21:51:1414384 auth_handler->SetGenerateExpectation(false, OK);
tfarina42834112016-09-22 13:38:2014385 rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]c871bce92010-07-15 21:51:1414386 if (rv == ERR_IO_PENDING)
14387 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114388 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614389 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214390 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5814391 EXPECT_TRUE(response->auth_challenge.has_value());
Raul Tambre8335a6d2019-02-21 16:57:4314392 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114393 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14394 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414395
[email protected]7ef4cbbb2011-02-06 11:19:1014396 // In between rounds, another request comes in for the same domain.
14397 // It should not be able to grab the TCP socket that trans has already
14398 // claimed.
bnc691fda62016-08-12 00:43:1614399 HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get());
[email protected]49639fa2011-12-20 23:22:4114400 TestCompletionCallback callback_compete;
tfarina42834112016-09-22 13:38:2014401 rv = trans_compete.Start(&request, callback_compete.callback(),
14402 NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114403 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]7ef4cbbb2011-02-06 11:19:1014404 // callback_compete.WaitForResult at this point would stall forever,
14405 // since the HttpNetworkTransaction does not release the request back to
14406 // the pool until after authentication completes.
14407
14408 // Second round of authentication.
[email protected]c871bce92010-07-15 21:51:1414409 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614410 rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414411 if (rv == ERR_IO_PENDING)
14412 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114413 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614414 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214415 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5814416 EXPECT_FALSE(response->auth_challenge.has_value());
Raul Tambre8335a6d2019-02-21 16:57:4314417 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114418 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14419 auth_handler->state());
[email protected]c871bce92010-07-15 21:51:1414420
[email protected]7ef4cbbb2011-02-06 11:19:1014421 // Third round of authentication.
[email protected]c871bce92010-07-15 21:51:1414422 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614423 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]c871bce92010-07-15 21:51:1414424 if (rv == ERR_IO_PENDING)
14425 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114426 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614427 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214428 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5814429 EXPECT_FALSE(response->auth_challenge.has_value());
Raul Tambre8335a6d2019-02-21 16:57:4314430 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
asanka463ca4262016-11-16 02:34:3114431 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_GENERATE_AUTH_TOKEN,
14432 auth_handler->state());
[email protected]eca50e122010-09-11 14:03:3014433
[email protected]7ef4cbbb2011-02-06 11:19:1014434 // Fourth round of authentication, which completes successfully.
[email protected]eca50e122010-09-11 14:03:3014435 auth_handler->SetGenerateExpectation(false, OK);
bnc691fda62016-08-12 00:43:1614436 rv = trans.RestartWithAuth(AuthCredentials(), callback.callback());
[email protected]eca50e122010-09-11 14:03:3014437 if (rv == ERR_IO_PENDING)
14438 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0114439 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614440 response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214441 ASSERT_TRUE(response);
Emily Starkf2c9bbd2019-04-09 17:08:5814442 EXPECT_FALSE(response->auth_challenge.has_value());
Raul Tambre8335a6d2019-02-21 16:57:4314443 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014444
asanka463ca4262016-11-16 02:34:3114445 // In WAIT_FOR_CHALLENGE, although in reality the auth handler is done. A real
14446 // auth handler should transition to a DONE state in concert with the remote
14447 // server. But that's not something we can test here with a mock handler.
14448 EXPECT_EQ(HttpAuthHandlerMock::State::WAIT_FOR_CHALLENGE,
14449 auth_handler->state());
14450
[email protected]7ef4cbbb2011-02-06 11:19:1014451 // Read the body since the fourth round was successful. This will also
14452 // release the socket back to the pool.
Victor Costan9c7302b2018-08-27 16:39:4414453 scoped_refptr<IOBufferWithSize> io_buf =
14454 base::MakeRefCounted<IOBufferWithSize>(50);
bnc691fda62016-08-12 00:43:1614455 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014456 if (rv == ERR_IO_PENDING)
14457 rv = callback.WaitForResult();
14458 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614459 rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014460 EXPECT_EQ(0, rv);
14461 // There are still 0 idle sockets, since the trans_compete transaction
14462 // will be handed it immediately after trans releases it to the group.
Raul Tambre8335a6d2019-02-21 16:57:4314463 EXPECT_EQ(0u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]7ef4cbbb2011-02-06 11:19:1014464
14465 // The competing request can now finish. Wait for the headers and then
14466 // read the body.
14467 rv = callback_compete.WaitForResult();
robpercival214763f2016-07-01 23:27:0114468 EXPECT_THAT(rv, IsOk());
bnc691fda62016-08-12 00:43:1614469 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014470 if (rv == ERR_IO_PENDING)
14471 rv = callback.WaitForResult();
14472 EXPECT_EQ(3, rv);
bnc691fda62016-08-12 00:43:1614473 rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback());
[email protected]7ef4cbbb2011-02-06 11:19:1014474 EXPECT_EQ(0, rv);
14475
14476 // Finally, the socket is released to the group.
Raul Tambre8335a6d2019-02-21 16:57:4314477 EXPECT_EQ(1u, transport_pool->IdleSocketCountInGroup(kSocketGroup));
[email protected]c871bce92010-07-15 21:51:1414478}
14479
[email protected]65041fa2010-05-21 06:56:5314480// This tests the case that a request is issued via http instead of spdy after
14481// npn is negotiated.
bncd16676a2016-07-20 16:23:0114482TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
[email protected]65041fa2010-05-21 06:56:5314483 HttpRequestInfo request;
14484 request.method = "GET";
bncce36dca22015-04-21 22:11:2314485 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014486 request.traffic_annotation =
14487 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]65041fa2010-05-21 06:56:5314488
14489 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2314490 MockWrite(
14491 "GET / HTTP/1.1\r\n"
14492 "Host: www.example.org\r\n"
14493 "Connection: keep-alive\r\n\r\n"),
[email protected]65041fa2010-05-21 06:56:5314494 };
14495
14496 MockRead data_reads[] = {
bncc958faa2015-07-31 18:14:5214497 MockRead("HTTP/1.1 200 OK\r\n"),
bnc2df4b522016-07-08 18:17:4314498 MockRead(kAlternativeServiceHttpHeader),
bncc958faa2015-07-31 18:14:5214499 MockRead("\r\n"),
14500 MockRead("hello world"),
14501 MockRead(SYNCHRONOUS, OK),
[email protected]65041fa2010-05-21 06:56:5314502 };
14503
[email protected]8ddf8322012-02-23 18:08:0614504 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614505 ssl.next_proto = kProtoHTTP11;
[email protected]65041fa2010-05-21 06:56:5314506
[email protected]bb88e1d32013-05-03 23:11:0714507 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]65041fa2010-05-21 06:56:5314508
Ryan Sleevib8d7ea02018-05-07 20:01:0114509 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]bb88e1d32013-05-03 23:11:0714510 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]65041fa2010-05-21 06:56:5314511
[email protected]49639fa2011-12-20 23:22:4114512 TestCompletionCallback callback;
[email protected]65041fa2010-05-21 06:56:5314513
danakj1fd259a02016-04-16 03:17:0914514 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614515 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]65041fa2010-05-21 06:56:5314516
tfarina42834112016-09-22 13:38:2014517 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
[email protected]65041fa2010-05-21 06:56:5314518
robpercival214763f2016-07-01 23:27:0114519 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14520 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]65041fa2010-05-21 06:56:5314521
bnc691fda62016-08-12 00:43:1614522 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214523 ASSERT_TRUE(response);
14524 ASSERT_TRUE(response->headers);
[email protected]65041fa2010-05-21 06:56:5314525 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14526
14527 std::string response_data;
bnc691fda62016-08-12 00:43:1614528 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
[email protected]65041fa2010-05-21 06:56:5314529 EXPECT_EQ("hello world", response_data);
14530
14531 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5214532 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]65041fa2010-05-21 06:56:5314533}
[email protected]26ef6582010-06-24 02:30:4714534
bnc55ff9da2015-08-19 18:42:3514535// Simulate the SSL handshake completing with an NPN negotiation followed by an
14536// immediate server closing of the socket.
14537// Regression test for https://crbug.com/46369.
bncd16676a2016-07-20 16:23:0114538TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
[email protected]26ef6582010-06-24 02:30:4714539 HttpRequestInfo request;
14540 request.method = "GET";
bncce36dca22015-04-21 22:11:2314541 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014542 request.traffic_annotation =
14543 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]26ef6582010-06-24 02:30:4714544
[email protected]8ddf8322012-02-23 18:08:0614545 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614546 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714547 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]26ef6582010-06-24 02:30:4714548
Ryan Hamilton0239aac2018-05-19 00:03:1314549 spdy::SpdySerializedFrame req(
14550 spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114551 MockWrite spdy_writes[] = {CreateMockWrite(req, 1)};
[email protected]26ef6582010-06-24 02:30:4714552
14553 MockRead spdy_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614554 MockRead(SYNCHRONOUS, 0, 0) // Not async - return 0 immediately.
[email protected]26ef6582010-06-24 02:30:4714555 };
14556
Ryan Sleevib8d7ea02018-05-07 20:01:0114557 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714558 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]26ef6582010-06-24 02:30:4714559
[email protected]49639fa2011-12-20 23:22:4114560 TestCompletionCallback callback;
[email protected]26ef6582010-06-24 02:30:4714561
danakj1fd259a02016-04-16 03:17:0914562 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1614563 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]26ef6582010-06-24 02:30:4714564
tfarina42834112016-09-22 13:38:2014565 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114566 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
14567 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]26ef6582010-06-24 02:30:4714568}
[email protected]65d34382010-07-01 18:12:2614569
[email protected]795cbf82013-07-22 09:37:2714570// A subclass of HttpAuthHandlerMock that records the request URL when
14571// it gets it. This is needed since the auth handler may get destroyed
14572// before we get a chance to query it.
14573class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
14574 public:
14575 explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
14576
Chris Watkins7a41d3552017-12-01 02:13:2714577 ~UrlRecordingHttpAuthHandlerMock() override = default;
[email protected]795cbf82013-07-22 09:37:2714578
14579 protected:
dchengb03027d2014-10-21 12:00:2014580 int GenerateAuthTokenImpl(const AuthCredentials* credentials,
14581 const HttpRequestInfo* request,
Bence Béky7236fb72018-08-01 14:35:0914582 CompletionOnceCallback callback,
dchengb03027d2014-10-21 12:00:2014583 std::string* auth_token) override {
[email protected]795cbf82013-07-22 09:37:2714584 *url_ = request->url;
14585 return HttpAuthHandlerMock::GenerateAuthTokenImpl(
Bence Béky7236fb72018-08-01 14:35:0914586 credentials, request, std::move(callback), auth_token);
[email protected]795cbf82013-07-22 09:37:2714587 }
14588
14589 private:
14590 GURL* url_;
14591};
14592
[email protected]8e6441ca2010-08-19 05:56:3814593// Test that if we cancel the transaction as the connection is completing, that
14594// everything tears down correctly.
bncd16676a2016-07-20 16:23:0114595TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
[email protected]8e6441ca2010-08-19 05:56:3814596 // Setup everything about the connection to complete synchronously, so that
14597 // after calling HttpNetworkTransaction::Start, the only thing we're waiting
14598 // for is the callback from the HttpStreamRequest.
14599 // Then cancel the transaction.
14600 // Verify that we don't crash.
[email protected]d973e99a2012-02-17 21:02:3614601 MockConnect mock_connect(SYNCHRONOUS, OK);
[email protected]8e6441ca2010-08-19 05:56:3814602 MockRead data_reads[] = {
[email protected]8ddf8322012-02-23 18:08:0614603 MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
14604 MockRead(SYNCHRONOUS, "hello world"),
14605 MockRead(SYNCHRONOUS, OK),
[email protected]8e6441ca2010-08-19 05:56:3814606 };
14607
[email protected]8e6441ca2010-08-19 05:56:3814608 HttpRequestInfo request;
14609 request.method = "GET";
bncce36dca22015-04-21 22:11:2314610 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014611 request.traffic_annotation =
14612 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8e6441ca2010-08-19 05:56:3814613
danakj1fd259a02016-04-16 03:17:0914614 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc87dcefc2017-05-25 12:47:5814615 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1914616 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]cb9bf6ca2011-01-28 13:15:2714617
Ryan Sleevib8d7ea02018-05-07 20:01:0114618 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]8e6441ca2010-08-19 05:56:3814619 data.set_connect_data(mock_connect);
[email protected]bb88e1d32013-05-03 23:11:0714620 session_deps_.socket_factory->AddSocketDataProvider(&data);
[email protected]8e6441ca2010-08-19 05:56:3814621
[email protected]49639fa2011-12-20 23:22:4114622 TestCompletionCallback callback;
[email protected]8e6441ca2010-08-19 05:56:3814623
vishal.b62985ca92015-04-17 08:45:5114624 BoundTestNetLog log;
[email protected]49639fa2011-12-20 23:22:4114625 int rv = trans->Start(&request, callback.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114626 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]8e6441ca2010-08-19 05:56:3814627 trans.reset(); // Cancel the transaction here.
14628
fdoray92e35a72016-06-10 15:54:5514629 base::RunLoop().RunUntilIdle();
[email protected]f45c1ee2010-08-03 00:54:3014630}
14631
[email protected]ecab6e052014-05-16 14:58:1214632// Test that if a transaction is cancelled after receiving the headers, the
14633// stream is drained properly and added back to the socket pool. The main
14634// purpose of this test is to make sure that an HttpStreamParser can be read
14635// from after the HttpNetworkTransaction and the objects it owns have been
14636// deleted.
14637// See http://crbug.com/368418
bncd16676a2016-07-20 16:23:0114638TEST_F(HttpNetworkTransactionTest, CancelAfterHeaders) {
[email protected]ecab6e052014-05-16 14:58:1214639 MockRead data_reads[] = {
14640 MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
14641 MockRead(ASYNC, "Content-Length: 2\r\n"),
14642 MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
14643 MockRead(ASYNC, "1"),
14644 // 2 async reads are necessary to trigger a ReadResponseBody call after the
14645 // HttpNetworkTransaction has been deleted.
14646 MockRead(ASYNC, "2"),
14647 MockRead(SYNCHRONOUS, ERR_IO_PENDING), // Should never read this.
14648 };
Ryan Sleevib8d7ea02018-05-07 20:01:0114649 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
[email protected]ecab6e052014-05-16 14:58:1214650 session_deps_.socket_factory->AddSocketDataProvider(&data);
14651
danakj1fd259a02016-04-16 03:17:0914652 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]ecab6e052014-05-16 14:58:1214653
14654 {
14655 HttpRequestInfo request;
14656 request.method = "GET";
bncce36dca22015-04-21 22:11:2314657 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014658 request.traffic_annotation =
14659 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]ecab6e052014-05-16 14:58:1214660
dcheng48459ac22014-08-26 00:46:4114661 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]ecab6e052014-05-16 14:58:1214662 TestCompletionCallback callback;
14663
tfarina42834112016-09-22 13:38:2014664 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0114665 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]ecab6e052014-05-16 14:58:1214666 callback.WaitForResult();
14667
14668 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214669 ASSERT_TRUE(response);
14670 EXPECT_TRUE(response->headers);
[email protected]ecab6e052014-05-16 14:58:1214671 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
14672
14673 // The transaction and HttpRequestInfo are deleted.
14674 }
14675
14676 // Let the HttpResponseBodyDrainer drain the socket.
fdoray92e35a72016-06-10 15:54:5514677 base::RunLoop().RunUntilIdle();
[email protected]ecab6e052014-05-16 14:58:1214678
14679 // Socket should now be idle, waiting to be reused.
dcheng48459ac22014-08-26 00:46:4114680 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]ecab6e052014-05-16 14:58:1214681}
14682
[email protected]76a505b2010-08-25 06:23:0014683// Test a basic GET request through a proxy.
bncd16676a2016-07-20 16:23:0114684TEST_F(HttpNetworkTransactionTest, ProxyGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914685 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914686 ProxyResolutionService::CreateFixedFromPacResult(
14687 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114688 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714689 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914690 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014691
[email protected]76a505b2010-08-25 06:23:0014692 HttpRequestInfo request;
14693 request.method = "GET";
bncce36dca22015-04-21 22:11:2314694 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014695 request.traffic_annotation =
14696 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014697
14698 MockWrite data_writes1[] = {
bncce36dca22015-04-21 22:11:2314699 MockWrite(
14700 "GET http://www.example.org/ HTTP/1.1\r\n"
14701 "Host: www.example.org\r\n"
14702 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014703 };
14704
14705 MockRead data_reads1[] = {
14706 MockRead("HTTP/1.1 200 OK\r\n"),
14707 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14708 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614709 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014710 };
14711
Ryan Sleevib8d7ea02018-05-07 20:01:0114712 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714713 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]76a505b2010-08-25 06:23:0014714
[email protected]49639fa2011-12-20 23:22:4114715 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014716
bnc691fda62016-08-12 00:43:1614717 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914718 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614719 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914720 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14721 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014722
bnc691fda62016-08-12 00:43:1614723 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114724 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014725
14726 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114727 EXPECT_THAT(rv, IsOk());
[email protected]76a505b2010-08-25 06:23:0014728
bnc691fda62016-08-12 00:43:1614729 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214730 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014731
14732 EXPECT_TRUE(response->headers->IsKeepAlive());
14733 EXPECT_EQ(200, response->headers->response_code());
14734 EXPECT_EQ(100, response->headers->GetContentLength());
14735 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714736 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14737 HostPortPair::FromString("myproxy:70")),
14738 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914739 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14740 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14741 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]76a505b2010-08-25 06:23:0014742 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
[email protected]029c83b62013-01-24 05:28:2014743
14744 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614745 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014746 TestLoadTimingNotReusedWithPac(load_timing_info,
14747 CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
[email protected]76a505b2010-08-25 06:23:0014748}
14749
14750// Test a basic HTTPS GET request through a proxy.
bncd16676a2016-07-20 16:23:0114751TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
Lily Houghton8c2f97d2018-01-22 05:06:5914752 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914753 ProxyResolutionService::CreateFixedFromPacResult(
14754 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114755 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714756 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914757 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014758
[email protected]76a505b2010-08-25 06:23:0014759 HttpRequestInfo request;
14760 request.method = "GET";
bncce36dca22015-04-21 22:11:2314761 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014762 request.traffic_annotation =
14763 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014764
14765 // Since we have proxy, should try to establish tunnel.
14766 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714767 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14768 "Host: www.example.org:443\r\n"
14769 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014770
rsleevidb16bb02015-11-12 23:47:1714771 MockWrite("GET / HTTP/1.1\r\n"
14772 "Host: www.example.org\r\n"
14773 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014774 };
14775
14776 MockRead data_reads1[] = {
14777 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14778
14779 MockRead("HTTP/1.1 200 OK\r\n"),
14780 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14781 MockRead("Content-Length: 100\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614782 MockRead(SYNCHRONOUS, OK),
[email protected]76a505b2010-08-25 06:23:0014783 };
14784
Ryan Sleevib8d7ea02018-05-07 20:01:0114785 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714786 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614787 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714788 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014789
[email protected]49639fa2011-12-20 23:22:4114790 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014791
bnc691fda62016-08-12 00:43:1614792 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
ryansturm49a8cb12016-06-15 16:51:0914793 BeforeHeadersSentHandler headers_handler;
bnc691fda62016-08-12 00:43:1614794 trans.SetBeforeHeadersSentCallback(
ryansturm49a8cb12016-06-15 16:51:0914795 base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent,
14796 base::Unretained(&headers_handler)));
[email protected]0b0bf032010-09-21 18:08:5014797
bnc691fda62016-08-12 00:43:1614798 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114799 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014800
14801 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114802 EXPECT_THAT(rv, IsOk());
mmenke43758e62015-05-04 21:09:4614803 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014804 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014805 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014806 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14807 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014808 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014809 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014810 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14811 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014812
bnc691fda62016-08-12 00:43:1614813 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214814 ASSERT_TRUE(response);
[email protected]76a505b2010-08-25 06:23:0014815
14816 EXPECT_TRUE(response->headers->IsKeepAlive());
14817 EXPECT_EQ(200, response->headers->response_code());
14818 EXPECT_EQ(100, response->headers->GetContentLength());
14819 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14820 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714821 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14822 HostPortPair::FromString("myproxy:70")),
14823 response->proxy_server);
ryansturm49a8cb12016-06-15 16:51:0914824 EXPECT_TRUE(headers_handler.observed_before_headers_sent());
14825 EXPECT_TRUE(headers_handler.observed_before_headers_sent_with_proxy());
14826 EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri());
[email protected]029c83b62013-01-24 05:28:2014827
14828 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614829 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
[email protected]029c83b62013-01-24 05:28:2014830 TestLoadTimingNotReusedWithPac(load_timing_info,
14831 CONNECT_TIMING_HAS_SSL_TIMES);
[email protected]76a505b2010-08-25 06:23:0014832}
14833
rsleevidb16bb02015-11-12 23:47:1714834// Test a basic HTTPS GET request through a proxy, connecting to an IPv6
14835// literal host.
bncd16676a2016-07-20 16:23:0114836TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetIPv6) {
Lily Houghton8c2f97d2018-01-22 05:06:5914837 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4914838 ProxyResolutionService::CreateFixedFromPacResult(
14839 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714840 BoundTestNetLog log;
14841 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914842 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
rsleevidb16bb02015-11-12 23:47:1714843
14844 HttpRequestInfo request;
14845 request.method = "GET";
Eric Romanda790f92018-11-07 19:17:1514846 request.url = GURL("https://[::2]:443/");
Ramin Halavatib5e433e62018-02-07 07:41:1014847 request.traffic_annotation =
14848 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
rsleevidb16bb02015-11-12 23:47:1714849
14850 // Since we have proxy, should try to establish tunnel.
14851 MockWrite data_writes1[] = {
Eric Romanda790f92018-11-07 19:17:1514852 MockWrite("CONNECT [::2]:443 HTTP/1.1\r\n"
14853 "Host: [::2]:443\r\n"
rsleevidb16bb02015-11-12 23:47:1714854 "Proxy-Connection: keep-alive\r\n\r\n"),
14855
14856 MockWrite("GET / HTTP/1.1\r\n"
Eric Romanda790f92018-11-07 19:17:1514857 "Host: [::2]\r\n"
rsleevidb16bb02015-11-12 23:47:1714858 "Connection: keep-alive\r\n\r\n"),
14859 };
14860
14861 MockRead data_reads1[] = {
14862 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
14863
14864 MockRead("HTTP/1.1 200 OK\r\n"),
14865 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
14866 MockRead("Content-Length: 100\r\n\r\n"),
14867 MockRead(SYNCHRONOUS, OK),
14868 };
14869
Ryan Sleevib8d7ea02018-05-07 20:01:0114870 StaticSocketDataProvider data1(data_reads1, data_writes1);
rsleevidb16bb02015-11-12 23:47:1714871 session_deps_.socket_factory->AddSocketDataProvider(&data1);
14872 SSLSocketDataProvider ssl(ASYNC, OK);
14873 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
14874
14875 TestCompletionCallback callback1;
14876
bnc691fda62016-08-12 00:43:1614877 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
rsleevidb16bb02015-11-12 23:47:1714878
bnc691fda62016-08-12 00:43:1614879 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114880 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
rsleevidb16bb02015-11-12 23:47:1714881
14882 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114883 EXPECT_THAT(rv, IsOk());
rsleevidb16bb02015-11-12 23:47:1714884 TestNetLogEntry::List entries;
14885 log.GetEntries(&entries);
14886 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014887 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14888 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714889 ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014890 entries, pos,
14891 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14892 NetLogEventPhase::NONE);
rsleevidb16bb02015-11-12 23:47:1714893
bnc691fda62016-08-12 00:43:1614894 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5214895 ASSERT_TRUE(response);
rsleevidb16bb02015-11-12 23:47:1714896
14897 EXPECT_TRUE(response->headers->IsKeepAlive());
14898 EXPECT_EQ(200, response->headers->response_code());
14899 EXPECT_EQ(100, response->headers->GetContentLength());
14900 EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
14901 EXPECT_TRUE(response->was_fetched_via_proxy);
tbansal2ecbbc72016-10-06 17:15:4714902 EXPECT_EQ(ProxyServer(ProxyServer::SCHEME_HTTP,
14903 HostPortPair::FromString("myproxy:70")),
14904 response->proxy_server);
rsleevidb16bb02015-11-12 23:47:1714905
14906 LoadTimingInfo load_timing_info;
bnc691fda62016-08-12 00:43:1614907 EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info));
rsleevidb16bb02015-11-12 23:47:1714908 TestLoadTimingNotReusedWithPac(load_timing_info,
14909 CONNECT_TIMING_HAS_SSL_TIMES);
14910}
14911
[email protected]76a505b2010-08-25 06:23:0014912// Test a basic HTTPS GET request through a proxy, but the server hangs up
14913// while establishing the tunnel.
bncd16676a2016-07-20 16:23:0114914TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
Ramin Halavatica8d5252018-03-12 05:33:4914915 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
14916 "myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5114917 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0714918 session_deps_.net_log = log.bound().net_log();
danakj1fd259a02016-04-16 03:17:0914919 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]76a505b2010-08-25 06:23:0014920
[email protected]76a505b2010-08-25 06:23:0014921 HttpRequestInfo request;
14922 request.method = "GET";
bncce36dca22015-04-21 22:11:2314923 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1014924 request.traffic_annotation =
14925 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]76a505b2010-08-25 06:23:0014926
14927 // Since we have proxy, should try to establish tunnel.
14928 MockWrite data_writes1[] = {
rsleevidb16bb02015-11-12 23:47:1714929 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
14930 "Host: www.example.org:443\r\n"
14931 "Proxy-Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014932
rsleevidb16bb02015-11-12 23:47:1714933 MockWrite("GET / HTTP/1.1\r\n"
14934 "Host: www.example.org\r\n"
14935 "Connection: keep-alive\r\n\r\n"),
[email protected]76a505b2010-08-25 06:23:0014936 };
14937
14938 MockRead data_reads1[] = {
[email protected]76a505b2010-08-25 06:23:0014939 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
[email protected]8ddf8322012-02-23 18:08:0614940 MockRead(ASYNC, 0, 0), // EOF
[email protected]76a505b2010-08-25 06:23:0014941 };
14942
Ryan Sleevib8d7ea02018-05-07 20:01:0114943 StaticSocketDataProvider data1(data_reads1, data_writes1);
[email protected]bb88e1d32013-05-03 23:11:0714944 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8ddf8322012-02-23 18:08:0614945 SSLSocketDataProvider ssl(ASYNC, OK);
[email protected]bb88e1d32013-05-03 23:11:0714946 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]76a505b2010-08-25 06:23:0014947
[email protected]49639fa2011-12-20 23:22:4114948 TestCompletionCallback callback1;
[email protected]76a505b2010-08-25 06:23:0014949
bnc691fda62016-08-12 00:43:1614950 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]0b0bf032010-09-21 18:08:5014951
bnc691fda62016-08-12 00:43:1614952 int rv = trans.Start(&request, callback1.callback(), log.bound());
robpercival214763f2016-07-01 23:27:0114953 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]76a505b2010-08-25 06:23:0014954
14955 rv = callback1.WaitForResult();
robpercival214763f2016-07-01 23:27:0114956 EXPECT_THAT(rv, IsError(ERR_EMPTY_RESPONSE));
mmenke43758e62015-05-04 21:09:4614957 TestNetLogEntry::List entries;
[email protected]b2fcd0e2010-12-01 15:19:4014958 log.GetEntries(&entries);
[email protected]76a505b2010-08-25 06:23:0014959 size_t pos = ExpectLogContainsSomewhere(
mikecirone8b85c432016-09-08 19:11:0014960 entries, 0, NetLogEventType::HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
14961 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014962 ExpectLogContainsSomewhere(
[email protected]b2fcd0e2010-12-01 15:19:4014963 entries, pos,
mikecirone8b85c432016-09-08 19:11:0014964 NetLogEventType::HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
14965 NetLogEventPhase::NONE);
[email protected]76a505b2010-08-25 06:23:0014966}
14967
[email protected]749eefa82010-09-13 22:14:0314968// Test for crbug.com/55424.
bncd16676a2016-07-20 16:23:0114969TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
Ryan Hamilton0239aac2018-05-19 00:03:1314970 spdy::SpdySerializedFrame req(
bnc38dcd392016-02-09 23:19:4914971 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
bncdf80d44fd2016-07-15 20:27:4114972 MockWrite spdy_writes[] = {CreateMockWrite(req, 0)};
[email protected]749eefa82010-09-13 22:14:0314973
Raul Tambre94493c652019-03-11 17:18:3514974 spdy::SpdySerializedFrame resp(
14975 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1314976 spdy::SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]749eefa82010-09-13 22:14:0314977 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4114978 CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3),
[email protected]749eefa82010-09-13 22:14:0314979 };
14980
Ryan Sleevib8d7ea02018-05-07 20:01:0114981 SequencedSocketData spdy_data(spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0714982 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]749eefa82010-09-13 22:14:0314983
[email protected]8ddf8322012-02-23 18:08:0614984 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3614985 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0714986 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
[email protected]749eefa82010-09-13 22:14:0314987
danakj1fd259a02016-04-16 03:17:0914988 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]749eefa82010-09-13 22:14:0314989
14990 // Set up an initial SpdySession in the pool to reuse.
bncce36dca22015-04-21 22:11:2314991 HostPortPair host_port_pair("www.example.org", 443);
[email protected]e6d017652013-05-17 18:01:4014992 SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
Matt Menke2436b2f2018-12-11 18:07:1114993 PRIVACY_MODE_DISABLED,
14994 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]795cbf82013-07-22 09:37:2714995 base::WeakPtr<SpdySession> spdy_session =
Bence Béky0ef1556e2017-06-30 19:52:5214996 CreateSpdySession(session.get(), key, NetLogWithSource());
[email protected]749eefa82010-09-13 22:14:0314997
14998 HttpRequestInfo request;
14999 request.method = "GET";
bncce36dca22015-04-21 22:11:2315000 request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1015001 request.traffic_annotation =
15002 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]749eefa82010-09-13 22:14:0315003
bnc691fda62016-08-12 00:43:1615004 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]749eefa82010-09-13 22:14:0315005
[email protected]41d64e82013-07-03 22:44:2615006 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015007 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115008 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15009 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]749eefa82010-09-13 22:14:0315010}
15011
[email protected]73b8dd222010-11-11 19:55:2415012// Given a net error, cause that error to be returned from the first Write()
bnc691fda62016-08-12 00:43:1615013// call and verify that the HttpNetworkTransaction fails with that error.
[email protected]23e482282013-06-14 16:08:0215014void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
[email protected]bb88e1d32013-05-03 23:11:0715015 int error, IoMode mode) {
ttuttle859dc7a2015-04-23 19:42:2915016 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715017 request_info.url = GURL("https://www.example.com/");
15018 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915019 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1015020 request_info.traffic_annotation =
15021 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715022
[email protected]8ddf8322012-02-23 18:08:0615023 SSLSocketDataProvider ssl_data(mode, OK);
ttuttle859dc7a2015-04-23 19:42:2915024 MockWrite data_writes[] = {
15025 MockWrite(mode, error),
[email protected]73b8dd222010-11-11 19:55:2415026 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115027 StaticSocketDataProvider data(base::span<MockRead>(), data_writes);
[email protected]bb88e1d32013-05-03 23:11:0715028 session_deps_.socket_factory->AddSocketDataProvider(&data);
15029 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
[email protected]73b8dd222010-11-11 19:55:2415030
danakj1fd259a02016-04-16 03:17:0915031 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615032 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]73b8dd222010-11-11 19:55:2415033
[email protected]49639fa2011-12-20 23:22:4115034 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015035 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
ttuttle859dc7a2015-04-23 19:42:2915036 if (rv == ERR_IO_PENDING)
[email protected]73b8dd222010-11-11 19:55:2415037 rv = callback.WaitForResult();
15038 ASSERT_EQ(error, rv);
15039}
15040
bncd16676a2016-07-20 16:23:0115041TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
[email protected]73b8dd222010-11-11 19:55:2415042 // Just check a grab bag of cert errors.
15043 static const int kErrors[] = {
15044 ERR_CERT_COMMON_NAME_INVALID,
15045 ERR_CERT_AUTHORITY_INVALID,
15046 ERR_CERT_DATE_INVALID,
15047 };
Avi Drissman4365a4782018-12-28 19:26:2415048 for (size_t i = 0; i < base::size(kErrors); i++) {
[email protected]8ddf8322012-02-23 18:08:0615049 CheckErrorIsPassedBack(kErrors[i], ASYNC);
15050 CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
[email protected]73b8dd222010-11-11 19:55:2415051 }
15052}
15053
[email protected]bd0b6772011-01-11 19:59:3015054// Ensure that a client certificate is removed from the SSL client auth
15055// cache when:
15056// 1) No proxy is involved.
15057// 2) TLS False Start is disabled.
15058// 3) The initial TLS handshake requests a client certificate.
15059// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0115060TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
ttuttle859dc7a2015-04-23 19:42:2915061 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715062 request_info.url = GURL("https://www.example.com/");
15063 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915064 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1015065 request_info.traffic_annotation =
15066 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715067
[email protected]bd0b6772011-01-11 19:59:3015068 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115069 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3015070
15071 // [ssl_]data1 contains the data for the first SSL handshake. When a
15072 // CertificateRequest is received for the first time, the handshake will
15073 // be aborted to allow the caller to provide a certificate.
ttuttle859dc7a2015-04-23 19:42:2915074 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3015075 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715076 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115077 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715078 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3015079
15080 // [ssl_]data2 contains the data for the second SSL handshake. When TLS
15081 // False Start is not being used, the result of the SSL handshake will be
15082 // returned as part of the SSLClientSocket::Connect() call. This test
15083 // matches the result of a server sending a handshake_failure alert,
15084 // rather than a Finished message, because it requires a client
15085 // certificate and none was supplied.
ttuttle859dc7a2015-04-23 19:42:2915086 SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]bd0b6772011-01-11 19:59:3015087 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715088 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
Ryan Sleevib8d7ea02018-05-07 20:01:0115089 StaticSocketDataProvider data2;
[email protected]bb88e1d32013-05-03 23:11:0715090 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015091
15092 // [ssl_]data3 contains the data for the third SSL handshake. When a
15093 // connection to a server fails during an SSL handshake,
Steven Valdez0ef94d02018-11-19 23:28:1315094 // HttpNetworkTransaction will attempt to fallback to TLSv1.2 if the previous
15095 // connection was attempted with TLSv1.3. This is transparent to the caller
[email protected]bd0b6772011-01-11 19:59:3015096 // of the HttpNetworkTransaction. Because this test failure is due to
15097 // requiring a client certificate, this fallback handshake should also
15098 // fail.
ttuttle859dc7a2015-04-23 19:42:2915099 SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
Steven Valdez0ef94d02018-11-19 23:28:1315100 ssl_data3.expected_ssl_version_max = SSL_PROTOCOL_VERSION_TLS1_2;
[email protected]bd0b6772011-01-11 19:59:3015101 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715102 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115103 StaticSocketDataProvider data3;
[email protected]bb88e1d32013-05-03 23:11:0715104 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015105
[email protected]80c75f682012-05-26 16:22:1715106 // [ssl_]data4 contains the data for the fourth SSL handshake. When a
15107 // connection to a server fails during an SSL handshake,
davidbenb937d6c2015-05-14 04:53:4215108 // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
15109 // connection was attempted with TLSv1.1. This is transparent to the caller
[email protected]80c75f682012-05-26 16:22:1715110 // of the HttpNetworkTransaction. Because this test failure is due to
15111 // requiring a client certificate, this fallback handshake should also
15112 // fail.
ttuttle859dc7a2015-04-23 19:42:2915113 SSLSocketDataProvider ssl_data4(ASYNC, ERR_SSL_PROTOCOL_ERROR);
[email protected]80c75f682012-05-26 16:22:1715114 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715115 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115116 StaticSocketDataProvider data4;
[email protected]bb88e1d32013-05-03 23:11:0715117 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715118
danakj1fd259a02016-04-16 03:17:0915119 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615120 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015121
[email protected]bd0b6772011-01-11 19:59:3015122 // Begin the SSL handshake with the peer. This consumes ssl_data1.
[email protected]49639fa2011-12-20 23:22:4115123 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015124 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115125 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015126
15127 // Complete the SSL handshake, which should abort due to requiring a
15128 // client certificate.
15129 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115130 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015131
15132 // Indicate that no certificate should be supplied. From the perspective
15133 // of SSLClientCertCache, NULL is just as meaningful as a real
15134 // certificate, so this is the same as supply a
15135 // legitimate-but-unacceptable certificate.
Raul Tambre94493c652019-03-11 17:18:3515136 rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
robpercival214763f2016-07-01 23:27:0115137 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015138
15139 // Ensure the certificate was added to the client auth cache before
15140 // allowing the connection to continue restarting.
15141 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415142 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115143 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415144 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215145 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015146
15147 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715148 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15149 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015150 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115151 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015152
15153 // Ensure that the client certificate is removed from the cache on a
15154 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115155 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415156 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015157}
15158
15159// Ensure that a client certificate is removed from the SSL client auth
15160// cache when:
15161// 1) No proxy is involved.
15162// 2) TLS False Start is enabled.
15163// 3) The initial TLS handshake requests a client certificate.
15164// 4) The client supplies an invalid/unacceptable certificate.
bncd16676a2016-07-20 16:23:0115165TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
ttuttle859dc7a2015-04-23 19:42:2915166 HttpRequestInfo request_info;
[email protected]cb9bf6ca2011-01-28 13:15:2715167 request_info.url = GURL("https://www.example.com/");
15168 request_info.method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915169 request_info.load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1015170 request_info.traffic_annotation =
15171 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]cb9bf6ca2011-01-28 13:15:2715172
[email protected]bd0b6772011-01-11 19:59:3015173 scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
[email protected]791879c2013-12-17 07:22:4115174 cert_request->host_and_port = HostPortPair("www.example.com", 443);
[email protected]bd0b6772011-01-11 19:59:3015175
15176 // When TLS False Start is used, SSLClientSocket::Connect() calls will
15177 // return successfully after reading up to the peer's Certificate message.
15178 // This is to allow the caller to call SSLClientSocket::Write(), which can
15179 // enqueue application data to be sent in the same packet as the
15180 // ChangeCipherSpec and Finished messages.
15181 // The actual handshake will be finished when SSLClientSocket::Read() is
15182 // called, which expects to process the peer's ChangeCipherSpec and
15183 // Finished messages. If there was an error negotiating with the peer,
15184 // such as due to the peer requiring a client certificate when none was
15185 // supplied, the alert sent by the peer won't be processed until Read() is
15186 // called.
15187
15188 // Like the non-False Start case, when a client certificate is requested by
15189 // the peer, the handshake is aborted during the Connect() call.
15190 // [ssl_]data1 represents the initial SSL handshake with the peer.
ttuttle859dc7a2015-04-23 19:42:2915191 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
[email protected]bd0b6772011-01-11 19:59:3015192 ssl_data1.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715193 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
Ryan Sleevib8d7ea02018-05-07 20:01:0115194 StaticSocketDataProvider data1;
[email protected]bb88e1d32013-05-03 23:11:0715195 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]bd0b6772011-01-11 19:59:3015196
15197 // When a client certificate is supplied, Connect() will not be aborted
15198 // when the peer requests the certificate. Instead, the handshake will
15199 // artificially succeed, allowing the caller to write the HTTP request to
15200 // the socket. The handshake messages are not processed until Read() is
15201 // called, which then detects that the handshake was aborted, due to the
15202 // peer sending a handshake_failure because it requires a client
15203 // certificate.
ttuttle859dc7a2015-04-23 19:42:2915204 SSLSocketDataProvider ssl_data2(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015205 ssl_data2.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715206 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
ttuttle859dc7a2015-04-23 19:42:2915207 MockRead data2_reads[] = {
15208 MockRead(ASYNC /* async */, ERR_SSL_PROTOCOL_ERROR),
[email protected]bd0b6772011-01-11 19:59:3015209 };
Ryan Sleevib8d7ea02018-05-07 20:01:0115210 StaticSocketDataProvider data2(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715211 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]bd0b6772011-01-11 19:59:3015212
15213 // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
[email protected]80c75f682012-05-26 16:22:1715214 // the data for the SSL handshake once the TLSv1.1 connection falls back to
15215 // TLSv1. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915216 SSLSocketDataProvider ssl_data3(ASYNC, OK);
[email protected]bd0b6772011-01-11 19:59:3015217 ssl_data3.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715218 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:0115219 StaticSocketDataProvider data3(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715220 session_deps_.socket_factory->AddSocketDataProvider(&data3);
[email protected]bd0b6772011-01-11 19:59:3015221
[email protected]80c75f682012-05-26 16:22:1715222 // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
15223 // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
ttuttle859dc7a2015-04-23 19:42:2915224 SSLSocketDataProvider ssl_data4(ASYNC, OK);
[email protected]80c75f682012-05-26 16:22:1715225 ssl_data4.cert_request_info = cert_request.get();
[email protected]bb88e1d32013-05-03 23:11:0715226 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
Ryan Sleevib8d7ea02018-05-07 20:01:0115227 StaticSocketDataProvider data4(data2_reads, base::span<MockWrite>());
[email protected]bb88e1d32013-05-03 23:11:0715228 session_deps_.socket_factory->AddSocketDataProvider(&data4);
[email protected]80c75f682012-05-26 16:22:1715229
[email protected]7799de12013-05-30 05:52:5115230 // Need one more if TLSv1.2 is enabled.
ttuttle859dc7a2015-04-23 19:42:2915231 SSLSocketDataProvider ssl_data5(ASYNC, OK);
[email protected]7799de12013-05-30 05:52:5115232 ssl_data5.cert_request_info = cert_request.get();
15233 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
Ryan Sleevib8d7ea02018-05-07 20:01:0115234 StaticSocketDataProvider data5(data2_reads, base::span<MockWrite>());
[email protected]7799de12013-05-30 05:52:5115235 session_deps_.socket_factory->AddSocketDataProvider(&data5);
15236
danakj1fd259a02016-04-16 03:17:0915237 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1615238 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]bd0b6772011-01-11 19:59:3015239
[email protected]bd0b6772011-01-11 19:59:3015240 // Begin the initial SSL handshake.
[email protected]49639fa2011-12-20 23:22:4115241 TestCompletionCallback callback;
tfarina42834112016-09-22 13:38:2015242 int rv = trans.Start(&request_info, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115243 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015244
15245 // Complete the SSL handshake, which should abort due to requiring a
15246 // client certificate.
15247 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115248 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
[email protected]bd0b6772011-01-11 19:59:3015249
15250 // Indicate that no certificate should be supplied. From the perspective
15251 // of SSLClientCertCache, NULL is just as meaningful as a real
15252 // certificate, so this is the same as supply a
15253 // legitimate-but-unacceptable certificate.
Raul Tambre94493c652019-03-11 17:18:3515254 rv = trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
robpercival214763f2016-07-01 23:27:0115255 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]bd0b6772011-01-11 19:59:3015256
15257 // Ensure the certificate was added to the client auth cache before
15258 // allowing the connection to continue restarting.
15259 scoped_refptr<X509Certificate> client_cert;
svaldez7872fd02015-11-19 21:10:5415260 scoped_refptr<SSLPrivateKey> client_private_key;
[email protected]791879c2013-12-17 07:22:4115261 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415262 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
wezca1070932016-05-26 20:30:5215263 ASSERT_FALSE(client_cert);
[email protected]bd0b6772011-01-11 19:59:3015264
[email protected]bd0b6772011-01-11 19:59:3015265 // Restart the handshake. This will consume ssl_data2, which fails, and
[email protected]80c75f682012-05-26 16:22:1715266 // then consume ssl_data3 and ssl_data4, both of which should also fail.
15267 // The result code is checked against what ssl_data4 should return.
[email protected]bd0b6772011-01-11 19:59:3015268 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0115269 ASSERT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
[email protected]bd0b6772011-01-11 19:59:3015270
15271 // Ensure that the client certificate is removed from the cache on a
15272 // handshake failure.
[email protected]791879c2013-12-17 07:22:4115273 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
svaldez7872fd02015-11-19 21:10:5415274 HostPortPair("www.example.com", 443), &client_cert, &client_private_key));
[email protected]bd0b6772011-01-11 19:59:3015275}
15276
[email protected]8c405132011-01-11 22:03:1815277// Ensure that a client certificate is removed from the SSL client auth
15278// cache when:
15279// 1) An HTTPS proxy is involved.
15280// 3) The HTTPS proxy requests a client certificate.
15281// 4) The client supplies an invalid/unacceptable certificate for the
15282// proxy.
bncd16676a2016-07-20 16:23:0115283TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
Ramin Halavatica8d5252018-03-12 05:33:4915284 session_deps_.proxy_resolution_service = ProxyResolutionService::CreateFixed(
15285 "https://proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5115286 BoundTestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0715287 session_deps_.net_log = log.bound().net_log();
[email protected]8c405132011-01-11 22:03:1815288
David Benjamin3b94b0f2019-04-25 23:07:5215289 auto cert_request = base::MakeRefCounted<SSLCertRequestInfo>();
[email protected]791879c2013-12-17 07:22:4115290 cert_request->host_and_port = HostPortPair("proxy", 70);
[email protected]8c405132011-01-11 22:03:1815291
David Benjamin3b94b0f2019-04-25 23:07:5215292 // Repeat the test for connecting to an HTTPS endpoint, then for connecting to
15293 // an HTTP endpoint.
ttuttle859dc7a2015-04-23 19:42:2915294 HttpRequestInfo requests[2];
[email protected]8c405132011-01-11 22:03:1815295 requests[0].url = GURL("https://www.example.com/");
15296 requests[0].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915297 requests[0].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1015298 requests[0].traffic_annotation =
15299 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815300
David Benjamin3b94b0f2019-04-25 23:07:5215301 // HTTPS requests are tunneled.
15302 MockWrite https_writes[] = {
15303 MockWrite("CONNECT www.example.com:443 HTTP/1.1\r\n"
15304 "Host: www.example.com:443\r\n"
15305 "Proxy-Connection: keep-alive\r\n\r\n"),
15306 };
15307
[email protected]8c405132011-01-11 22:03:1815308 requests[1].url = GURL("http://www.example.com/");
15309 requests[1].method = "GET";
ttuttle859dc7a2015-04-23 19:42:2915310 requests[1].load_flags = LOAD_NORMAL;
Ramin Halavatib5e433e62018-02-07 07:41:1015311 requests[1].traffic_annotation =
15312 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]8c405132011-01-11 22:03:1815313
David Benjamin3b94b0f2019-04-25 23:07:5215314 // HTTP requests are not.
15315 MockWrite http_writes[] = {
15316 MockWrite("GET http://www.example.com/ HTTP/1.1\r\n"
15317 "Host: www.example.com\r\n"
15318 "Proxy-Connection: keep-alive\r\n\r\n"),
15319 };
[email protected]8c405132011-01-11 22:03:1815320
David Benjamin3b94b0f2019-04-25 23:07:5215321 // When the server rejects the client certificate, it will close the
15322 // connection. In TLS 1.2, this is signaled out of Connect(). In TLS 1.3 (or
15323 // TLS 1.2 with False Start), the error is returned out of the first Read().
15324 for (bool reject_in_connect : {true, false}) {
15325 SCOPED_TRACE(reject_in_connect);
15326 // Client certificate errors are typically signaled with
15327 // ERR_BAD_SSL_CLIENT_AUTH_CERT, but sometimes the server gives an arbitrary
15328 // protocol error.
15329 for (Error reject_error :
15330 {ERR_SSL_PROTOCOL_ERROR, ERR_BAD_SSL_CLIENT_AUTH_CERT}) {
15331 SCOPED_TRACE(reject_error);
15332 // Tunneled and non-tunneled requests are handled differently. Test both.
15333 for (const HttpRequestInfo& request : requests) {
15334 SCOPED_TRACE(request.url);
[email protected]8c405132011-01-11 22:03:1815335
David Benjamin3b94b0f2019-04-25 23:07:5215336 session_deps_.socket_factory =
15337 std::make_unique<MockClientSocketFactory>();
[email protected]8c405132011-01-11 22:03:1815338
David Benjamin3b94b0f2019-04-25 23:07:5215339 // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
15340 // [ssl_]data[1-2]. [ssl_]data3 is not needed because we do not retry
15341 // for proxies. Rather than represending the endpoint
15342 // (www.example.com:443), they represent failures with the HTTPS proxy
15343 // (proxy:70).
15344 SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
15345 ssl_data1.cert_request_info = cert_request.get();
15346 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
15347 StaticSocketDataProvider data1;
15348 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8c405132011-01-11 22:03:1815349
David Benjamin3b94b0f2019-04-25 23:07:5215350 base::Optional<SSLSocketDataProvider> ssl_data2;
15351 base::Optional<StaticSocketDataProvider> data2;
15352 MockRead error_in_read[] = {MockRead(ASYNC, reject_error)};
15353 if (reject_in_connect) {
15354 ssl_data2.emplace(ASYNC, reject_error);
15355 // There are no reads or writes.
15356 data2.emplace();
15357 } else {
15358 ssl_data2.emplace(ASYNC, OK);
15359 // We will get one Write() in before observing the error in Read().
15360 if (request.url.SchemeIsCryptographic()) {
15361 data2.emplace(error_in_read, https_writes);
15362 } else {
15363 data2.emplace(error_in_read, http_writes);
15364 }
15365 }
15366 ssl_data2->cert_request_info = cert_request.get();
[email protected]8c405132011-01-11 22:03:1815367
David Benjamin3b94b0f2019-04-25 23:07:5215368 session_deps_.socket_factory->AddSSLSocketDataProvider(
15369 &ssl_data2.value());
15370 session_deps_.socket_factory->AddSocketDataProvider(&data2.value());
[email protected]8c405132011-01-11 22:03:1815371
David Benjamin3b94b0f2019-04-25 23:07:5215372 std::unique_ptr<HttpNetworkSession> session =
15373 CreateSession(&session_deps_);
15374 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
15375
15376 // Begin the SSL handshake with the proxy.
15377 TestCompletionCallback callback;
15378 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
15379 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
15380
15381 // Complete the SSL handshake, which should abort due to requiring a
15382 // client certificate.
15383 rv = callback.WaitForResult();
15384 ASSERT_THAT(rv, IsError(ERR_SSL_CLIENT_AUTH_CERT_NEEDED));
15385
15386 // Indicate that no certificate should be supplied. From the
15387 // perspective of SSLClientCertCache, NULL is just as meaningful as a
15388 // real certificate, so this is the same as supply a
15389 // legitimate-but-unacceptable certificate.
15390 rv =
15391 trans.RestartWithCertificate(nullptr, nullptr, callback.callback());
15392 ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
15393
15394 // Ensure the certificate was added to the client auth cache before
15395 // allowing the connection to continue restarting.
15396 scoped_refptr<X509Certificate> client_cert;
15397 scoped_refptr<SSLPrivateKey> client_private_key;
15398 ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
15399 HostPortPair("proxy", 70), &client_cert, &client_private_key));
15400 ASSERT_FALSE(client_cert);
15401 // Ensure the certificate was NOT cached for the endpoint. This only
15402 // applies to HTTPS requests, but is fine to check for HTTP requests.
15403 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
15404 HostPortPair("www.example.com", 443), &client_cert,
15405 &client_private_key));
15406
15407 // Restart the handshake. This will consume ssl_data2. The result code
15408 // is checked against what ssl_data2 should return.
15409 rv = callback.WaitForResult();
15410 ASSERT_THAT(rv, AnyOf(IsError(ERR_PROXY_CONNECTION_FAILED),
15411 IsError(reject_error)));
15412
15413 // Now that the new handshake has failed, ensure that the client
15414 // certificate was removed from the client auth cache.
15415 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
15416 HostPortPair("proxy", 70), &client_cert, &client_private_key));
15417 ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
15418 HostPortPair("www.example.com", 443), &client_cert,
15419 &client_private_key));
15420 }
15421 }
[email protected]8c405132011-01-11 22:03:1815422 }
15423}
15424
bncd16676a2016-07-20 16:23:0115425TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) {
[email protected]e3ceb682011-06-28 23:55:4615426 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915427 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915428 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615429
bnc032658ba2016-09-26 18:17:1515430 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615431
Ryan Hamilton0239aac2018-05-19 00:03:1315432 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915433 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815434 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315435 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715436 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615437 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115438 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615439 };
Ryan Hamilton0239aac2018-05-19 00:03:1315440 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515441 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315442 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115443 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315444 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515445 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315446 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115447 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615448 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115449 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15450 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315451 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615452 };
15453
eroman36d84e54432016-03-17 03:23:0215454 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215455 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115456 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715457 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615458
[email protected]aa22b242011-11-16 18:58:2915459 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615460 HttpRequestInfo request1;
15461 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315462 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615463 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015464 request1.traffic_annotation =
15465 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015466 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615467
tfarina42834112016-09-22 13:38:2015468 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115469 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15470 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615471
15472 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215473 ASSERT_TRUE(response);
15474 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215475 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615476
15477 std::string response_data;
robpercival214763f2016-07-01 23:27:0115478 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615479 EXPECT_EQ("hello!", response_data);
15480
bnca4d611d2016-09-22 19:55:3715481 // Preload mail.example.com into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315482 rv = session_deps_.host_resolver->LoadIntoCache(
15483 HostPortPair("mail.example.com", 443), base::nullopt);
robpercival214763f2016-07-01 23:27:0115484 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615485
15486 HttpRequestInfo request2;
15487 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715488 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615489 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015490 request2.traffic_annotation =
15491 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015492 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615493
tfarina42834112016-09-22 13:38:2015494 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115495 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15496 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615497
15498 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215499 ASSERT_TRUE(response);
15500 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215501 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615502 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215503 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115504 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615505 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615506}
15507
bncd16676a2016-07-20 16:23:0115508TEST_F(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
[email protected]d2b5f092012-06-08 23:55:0215509 // Set up a special HttpNetworkSession with a MockCachingHostResolver.
Jeremy Roman0579ed62017-08-29 15:56:1915510 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
danakj1fd259a02016-04-16 03:17:0915511 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]d2b5f092012-06-08 23:55:0215512
bnc032658ba2016-09-26 18:17:1515513 AddSSLSocketData();
[email protected]d2b5f092012-06-08 23:55:0215514
Ryan Hamilton0239aac2018-05-19 00:03:1315515 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915516 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815517 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315518 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715519 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]d2b5f092012-06-08 23:55:0215520 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115521 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]d2b5f092012-06-08 23:55:0215522 };
Ryan Hamilton0239aac2018-05-19 00:03:1315523 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515524 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315525 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115526 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315527 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515528 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315529 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115530 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]d2b5f092012-06-08 23:55:0215531 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115532 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15533 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315534 MockRead(ASYNC, 0, 6),
[email protected]d2b5f092012-06-08 23:55:0215535 };
15536
eroman36d84e54432016-03-17 03:23:0215537 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215538 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115539 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715540 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]d2b5f092012-06-08 23:55:0215541
15542 TestCompletionCallback callback;
15543 HttpRequestInfo request1;
15544 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315545 request1.url = GURL("https://www.example.org/");
[email protected]d2b5f092012-06-08 23:55:0215546 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015547 request1.traffic_annotation =
15548 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015549 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215550
tfarina42834112016-09-22 13:38:2015551 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115552 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15553 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215554
15555 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215556 ASSERT_TRUE(response);
15557 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215558 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215559
15560 std::string response_data;
robpercival214763f2016-07-01 23:27:0115561 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215562 EXPECT_EQ("hello!", response_data);
15563
15564 HttpRequestInfo request2;
15565 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715566 request2.url = GURL("https://mail.example.com/");
[email protected]d2b5f092012-06-08 23:55:0215567 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015568 request2.traffic_annotation =
15569 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015570 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]d2b5f092012-06-08 23:55:0215571
tfarina42834112016-09-22 13:38:2015572 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115573 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15574 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215575
15576 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215577 ASSERT_TRUE(response);
15578 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215579 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]d2b5f092012-06-08 23:55:0215580 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215581 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115582 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]d2b5f092012-06-08 23:55:0215583 EXPECT_EQ("hello!", response_data);
[email protected]d2b5f092012-06-08 23:55:0215584}
15585
bnc8016c1f2017-03-31 02:11:2915586// Regression test for https://crbug.com/546991.
15587// The server might not be able to serve an IP pooled request, and might send a
15588// 421 Misdirected Request response status to indicate this.
15589// HttpNetworkTransaction should reset the request and retry without IP pooling.
15590TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) {
15591 // Two hosts resolve to the same IP address.
15592 const std::string ip_addr = "1.2.3.4";
15593 IPAddress ip;
15594 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15595 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15596
Jeremy Roman0579ed62017-08-29 15:56:1915597 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bnc8016c1f2017-03-31 02:11:2915598 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15599 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15600
15601 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15602
15603 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315604 spdy::SpdySerializedFrame req1(
bnc8016c1f2017-03-31 02:11:2915605 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15606 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315607 spdy::SpdySerializedFrame req2(
bnc8016c1f2017-03-31 02:11:2915608 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315609 spdy::SpdySerializedFrame rst(
15610 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
bnc8016c1f2017-03-31 02:11:2915611 MockWrite writes1[] = {
15612 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15613 CreateMockWrite(rst, 6),
15614 };
15615
15616 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315617 spdy::SpdySerializedFrame resp1(
15618 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15619 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15620 spdy::SpdyHeaderBlock response_headers;
15621 response_headers[spdy::kHttp2StatusHeader] = "421";
15622 spdy::SpdySerializedFrame resp2(
bnc8016c1f2017-03-31 02:11:2915623 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
15624 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15625 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15626
15627 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115628 SequencedSocketData data1(connect1, reads1, writes1);
bnc8016c1f2017-03-31 02:11:2915629 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15630
15631 AddSSLSocketData();
15632
15633 // Retry the second request on a second connection.
15634 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315635 spdy::SpdySerializedFrame req3(
bnc8016c1f2017-03-31 02:11:2915636 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15637 MockWrite writes2[] = {
15638 CreateMockWrite(req3, 0),
15639 };
15640
Ryan Hamilton0239aac2018-05-19 00:03:1315641 spdy::SpdySerializedFrame resp3(
15642 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
15643 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
bnc8016c1f2017-03-31 02:11:2915644 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15645 MockRead(ASYNC, 0, 3)};
15646
15647 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115648 SequencedSocketData data2(connect2, reads2, writes2);
bnc8016c1f2017-03-31 02:11:2915649 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15650
15651 AddSSLSocketData();
15652
15653 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315654 int rv = session_deps_.host_resolver->LoadIntoCache(
15655 HostPortPair("mail.example.com", 443), base::nullopt);
bnc8016c1f2017-03-31 02:11:2915656 EXPECT_THAT(rv, IsOk());
15657
15658 HttpRequestInfo request1;
15659 request1.method = "GET";
15660 request1.url = GURL("https://www.example.org/");
15661 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015662 request1.traffic_annotation =
15663 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915664 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15665
Eric Orthf4db66a2019-02-19 21:35:3315666 TestCompletionCallback callback;
bnc8016c1f2017-03-31 02:11:2915667 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15668 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15669 rv = callback.WaitForResult();
15670 EXPECT_THAT(rv, IsOk());
15671
15672 const HttpResponseInfo* response = trans1.GetResponseInfo();
15673 ASSERT_TRUE(response);
15674 ASSERT_TRUE(response->headers);
15675 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15676 EXPECT_TRUE(response->was_fetched_via_spdy);
15677 EXPECT_TRUE(response->was_alpn_negotiated);
15678 std::string response_data;
15679 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15680 EXPECT_EQ("hello!", response_data);
15681
15682 HttpRequestInfo request2;
15683 request2.method = "GET";
15684 request2.url = GURL("https://mail.example.org/");
15685 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015686 request2.traffic_annotation =
15687 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc8016c1f2017-03-31 02:11:2915688 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15689
15690 BoundTestNetLog log;
15691 rv = trans2.Start(&request2, callback.callback(), log.bound());
15692 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15693 rv = callback.WaitForResult();
15694 EXPECT_THAT(rv, IsOk());
15695
15696 response = trans2.GetResponseInfo();
15697 ASSERT_TRUE(response);
15698 ASSERT_TRUE(response->headers);
15699 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15700 EXPECT_TRUE(response->was_fetched_via_spdy);
15701 EXPECT_TRUE(response->was_alpn_negotiated);
15702 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15703 EXPECT_EQ("hello!", response_data);
15704
15705 TestNetLogEntry::List entries;
15706 log.GetEntries(&entries);
davidbence688ae2017-05-04 15:12:5915707 ExpectLogContainsSomewhere(
15708 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_MISDIRECTED_REQUEST,
bnc8016c1f2017-03-31 02:11:2915709 NetLogEventPhase::NONE);
davidbence688ae2017-05-04 15:12:5915710}
15711
15712// Test that HTTP 421 responses are properly returned to the caller if received
15713// on the retry as well. HttpNetworkTransaction should not infinite loop or lose
15714// portions of the response.
15715TEST_F(HttpNetworkTransactionTest, ReturnHTTP421OnRetry) {
15716 // Two hosts resolve to the same IP address.
15717 const std::string ip_addr = "1.2.3.4";
15718 IPAddress ip;
15719 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
15720 IPEndPoint peer_addr = IPEndPoint(ip, 443);
15721
Jeremy Roman0579ed62017-08-29 15:56:1915722 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
davidbence688ae2017-05-04 15:12:5915723 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
15724 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
15725
15726 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
15727
15728 // Two requests on the first connection.
Ryan Hamilton0239aac2018-05-19 00:03:1315729 spdy::SpdySerializedFrame req1(
davidbence688ae2017-05-04 15:12:5915730 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
15731 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315732 spdy::SpdySerializedFrame req2(
davidbence688ae2017-05-04 15:12:5915733 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1315734 spdy::SpdySerializedFrame rst(
15735 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
davidbence688ae2017-05-04 15:12:5915736 MockWrite writes1[] = {
15737 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3),
15738 CreateMockWrite(rst, 6),
15739 };
15740
15741 // The first one succeeds, the second gets error 421 Misdirected Request.
Ryan Hamilton0239aac2018-05-19 00:03:1315742 spdy::SpdySerializedFrame resp1(
15743 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
15744 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
15745 spdy::SpdyHeaderBlock response_headers;
15746 response_headers[spdy::kHttp2StatusHeader] = "421";
15747 spdy::SpdySerializedFrame resp2(
davidbence688ae2017-05-04 15:12:5915748 spdy_util_.ConstructSpdyReply(3, response_headers.Clone()));
15749 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
15750 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
15751
15752 MockConnect connect1(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115753 SequencedSocketData data1(connect1, reads1, writes1);
davidbence688ae2017-05-04 15:12:5915754 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15755
15756 AddSSLSocketData();
15757
15758 // Retry the second request on a second connection. It returns 421 Misdirected
15759 // Retry again.
15760 SpdyTestUtil spdy_util2;
Ryan Hamilton0239aac2018-05-19 00:03:1315761 spdy::SpdySerializedFrame req3(
davidbence688ae2017-05-04 15:12:5915762 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
15763 MockWrite writes2[] = {
15764 CreateMockWrite(req3, 0),
15765 };
15766
Ryan Hamilton0239aac2018-05-19 00:03:1315767 spdy::SpdySerializedFrame resp3(
davidbence688ae2017-05-04 15:12:5915768 spdy_util2.ConstructSpdyReply(1, std::move(response_headers)));
Ryan Hamilton0239aac2018-05-19 00:03:1315769 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
davidbence688ae2017-05-04 15:12:5915770 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
15771 MockRead(ASYNC, 0, 3)};
15772
15773 MockConnect connect2(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115774 SequencedSocketData data2(connect2, reads2, writes2);
davidbence688ae2017-05-04 15:12:5915775 session_deps_.socket_factory->AddSocketDataProvider(&data2);
15776
15777 AddSSLSocketData();
15778
15779 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315780 int rv = session_deps_.host_resolver->LoadIntoCache(
15781 HostPortPair("mail.example.com", 443), base::nullopt);
davidbence688ae2017-05-04 15:12:5915782 EXPECT_THAT(rv, IsOk());
15783
15784 HttpRequestInfo request1;
15785 request1.method = "GET";
15786 request1.url = GURL("https://www.example.org/");
15787 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015788 request1.traffic_annotation =
15789 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915790 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
15791
Eric Orthf4db66a2019-02-19 21:35:3315792 TestCompletionCallback callback;
davidbence688ae2017-05-04 15:12:5915793 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
15794 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15795 rv = callback.WaitForResult();
15796 EXPECT_THAT(rv, IsOk());
15797
15798 const HttpResponseInfo* response = trans1.GetResponseInfo();
15799 ASSERT_TRUE(response);
15800 ASSERT_TRUE(response->headers);
15801 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
15802 EXPECT_TRUE(response->was_fetched_via_spdy);
15803 EXPECT_TRUE(response->was_alpn_negotiated);
15804 std::string response_data;
15805 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
15806 EXPECT_EQ("hello!", response_data);
15807
15808 HttpRequestInfo request2;
15809 request2.method = "GET";
15810 request2.url = GURL("https://mail.example.org/");
15811 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015812 request2.traffic_annotation =
15813 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
davidbence688ae2017-05-04 15:12:5915814 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
15815
15816 BoundTestNetLog log;
15817 rv = trans2.Start(&request2, callback.callback(), log.bound());
15818 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15819 rv = callback.WaitForResult();
15820 EXPECT_THAT(rv, IsOk());
15821
15822 // After a retry, the 421 Misdirected Request is reported back up to the
15823 // caller.
15824 response = trans2.GetResponseInfo();
15825 ASSERT_TRUE(response);
15826 ASSERT_TRUE(response->headers);
15827 EXPECT_EQ("HTTP/1.1 421", response->headers->GetStatusLine());
15828 EXPECT_TRUE(response->was_fetched_via_spdy);
15829 EXPECT_TRUE(response->was_alpn_negotiated);
15830 EXPECT_TRUE(response->ssl_info.cert);
15831 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
15832 EXPECT_EQ("hello!", response_data);
bnc8016c1f2017-03-31 02:11:2915833}
15834
bncd16676a2016-07-20 16:23:0115835TEST_F(HttpNetworkTransactionTest,
mmenke5c642132015-06-02 16:05:1315836 UseIPConnectionPoolingWithHostCacheExpiration) {
Eric Orth1da75de2019-02-20 21:10:3415837 // Set up HostResolver to invalidate cached entries after 1 cached resolve.
15838 session_deps_.host_resolver =
15839 std::make_unique<MockCachingHostResolver>(1 /* cache_invalidation_num */);
danakj1fd259a02016-04-16 03:17:0915840 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]e3ceb682011-06-28 23:55:4615841
bnc032658ba2016-09-26 18:17:1515842 AddSSLSocketData();
[email protected]e3ceb682011-06-28 23:55:4615843
Ryan Hamilton0239aac2018-05-19 00:03:1315844 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4915845 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
rdsmithebb50aa2015-11-12 03:44:3815846 spdy_util_.UpdateWithStreamDestruction(1);
Ryan Hamilton0239aac2018-05-19 00:03:1315847 spdy::SpdySerializedFrame host2_req(
bnca4d611d2016-09-22 19:55:3715848 spdy_util_.ConstructSpdyGet("https://mail.example.com", 3, LOWEST));
[email protected]e3ceb682011-06-28 23:55:4615849 MockWrite spdy_writes[] = {
bncdf80d44fd2016-07-15 20:27:4115850 CreateMockWrite(host1_req, 0), CreateMockWrite(host2_req, 3),
[email protected]e3ceb682011-06-28 23:55:4615851 };
Ryan Hamilton0239aac2018-05-19 00:03:1315852 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3515853 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315854 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4115855 spdy_util_.ConstructSpdyDataFrame(1, true));
Ryan Hamilton0239aac2018-05-19 00:03:1315856 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3515857 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1315858 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4115859 spdy_util_.ConstructSpdyDataFrame(3, true));
[email protected]e3ceb682011-06-28 23:55:4615860 MockRead spdy_reads[] = {
bncdf80d44fd2016-07-15 20:27:4115861 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
15862 CreateMockRead(host2_resp, 4), CreateMockRead(host2_resp_body, 5),
rch8e6c6c42015-05-01 14:05:1315863 MockRead(ASYNC, 0, 6),
[email protected]e3ceb682011-06-28 23:55:4615864 };
15865
eroman36d84e54432016-03-17 03:23:0215866 IPEndPoint peer_addr(IPAddress::IPv4Localhost(), 443);
[email protected]d2b5f092012-06-08 23:55:0215867 MockConnect connect(ASYNC, OK, peer_addr);
Ryan Sleevib8d7ea02018-05-07 20:01:0115868 SequencedSocketData spdy_data(connect, spdy_reads, spdy_writes);
[email protected]bb88e1d32013-05-03 23:11:0715869 session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
[email protected]e3ceb682011-06-28 23:55:4615870
[email protected]aa22b242011-11-16 18:58:2915871 TestCompletionCallback callback;
[email protected]e3ceb682011-06-28 23:55:4615872 HttpRequestInfo request1;
15873 request1.method = "GET";
bncce36dca22015-04-21 22:11:2315874 request1.url = GURL("https://www.example.org/");
[email protected]e3ceb682011-06-28 23:55:4615875 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015876 request1.traffic_annotation =
15877 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015878 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615879
tfarina42834112016-09-22 13:38:2015880 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115881 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15882 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615883
15884 const HttpResponseInfo* response = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5215885 ASSERT_TRUE(response);
15886 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215887 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615888
15889 std::string response_data;
robpercival214763f2016-07-01 23:27:0115890 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615891 EXPECT_EQ("hello!", response_data);
15892
15893 // Preload cache entries into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3315894 rv = session_deps_.host_resolver->LoadIntoCache(
15895 HostPortPair("mail.example.com", 443), base::nullopt);
robpercival214763f2016-07-01 23:27:0115896 EXPECT_THAT(rv, IsOk());
[email protected]e3ceb682011-06-28 23:55:4615897
15898 HttpRequestInfo request2;
15899 request2.method = "GET";
bnca4d611d2016-09-22 19:55:3715900 request2.url = GURL("https://mail.example.com/");
[email protected]e3ceb682011-06-28 23:55:4615901 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015902 request2.traffic_annotation =
15903 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015904 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
[email protected]e3ceb682011-06-28 23:55:4615905
tfarina42834112016-09-22 13:38:2015906 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0115907 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
15908 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615909
15910 response = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5215911 ASSERT_TRUE(response);
15912 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0215913 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]e3ceb682011-06-28 23:55:4615914 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5215915 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0115916 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
[email protected]e3ceb682011-06-28 23:55:4615917 EXPECT_EQ("hello!", response_data);
[email protected]e3ceb682011-06-28 23:55:4615918}
15919
bncd16676a2016-07-20 16:23:0115920TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
bncce36dca22015-04-21 22:11:2315921 const std::string https_url = "https://www.example.org:8080/";
15922 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0415923
15924 // SPDY GET for HTTPS URL
Ryan Hamilton0239aac2018-05-19 00:03:1315925 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4915926 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
[email protected]8450d722012-07-02 19:14:0415927
15928 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4115929 CreateMockWrite(req1, 0),
[email protected]8450d722012-07-02 19:14:0415930 };
15931
Raul Tambre94493c652019-03-11 17:18:3515932 spdy::SpdySerializedFrame resp1(
15933 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1315934 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4115935 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
mmenkee24011922015-12-17 22:12:5915936 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
[email protected]8450d722012-07-02 19:14:0415937
Ryan Sleevib8d7ea02018-05-07 20:01:0115938 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0415939 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5715940 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0415941
15942 // HTTP GET for the HTTP URL
15943 MockWrite writes2[] = {
rch8e6c6c42015-05-01 14:05:1315944 MockWrite(ASYNC, 0,
lgarrona91df87f2014-12-05 00:51:3415945 "GET / HTTP/1.1\r\n"
bncce36dca22015-04-21 22:11:2315946 "Host: www.example.org:8080\r\n"
lgarrona91df87f2014-12-05 00:51:3415947 "Connection: keep-alive\r\n\r\n"),
[email protected]8450d722012-07-02 19:14:0415948 };
15949
15950 MockRead reads2[] = {
rch8e6c6c42015-05-01 14:05:1315951 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
15952 MockRead(ASYNC, 2, "hello"),
15953 MockRead(ASYNC, OK, 3),
[email protected]8450d722012-07-02 19:14:0415954 };
15955
Ryan Sleevib8d7ea02018-05-07 20:01:0115956 SequencedSocketData data2(reads2, writes2);
[email protected]8450d722012-07-02 19:14:0415957
[email protected]8450d722012-07-02 19:14:0415958 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3615959 ssl.next_proto = kProtoHTTP2;
[email protected]bb88e1d32013-05-03 23:11:0715960 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
15961 session_deps_.socket_factory->AddSocketDataProvider(&data1);
15962 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]8450d722012-07-02 19:14:0415963
danakj1fd259a02016-04-16 03:17:0915964 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]8450d722012-07-02 19:14:0415965
15966 // Start the first transaction to set up the SpdySession
15967 HttpRequestInfo request1;
15968 request1.method = "GET";
15969 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0415970 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015971 request1.traffic_annotation =
15972 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015973 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0415974 TestCompletionCallback callback1;
15975 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015976 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515977 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415978
robpercival214763f2016-07-01 23:27:0115979 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415980 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
15981
15982 // Now, start the HTTP request
15983 HttpRequestInfo request2;
15984 request2.method = "GET";
15985 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0415986 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1015987 request2.traffic_annotation =
15988 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5015989 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0415990 TestCompletionCallback callback2;
15991 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2015992 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5515993 base::RunLoop().RunUntilIdle();
[email protected]8450d722012-07-02 19:14:0415994
robpercival214763f2016-07-01 23:27:0115995 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]8450d722012-07-02 19:14:0415996 EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
15997}
15998
bnc5452e2a2015-05-08 16:27:4215999// Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
16000// with the alternative server. That connection should not be used.
bncd16676a2016-07-20 16:23:0116001TEST_F(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
bnc8bef8da22016-05-30 01:28:2516002 url::SchemeHostPort server("https", "www.example.org", 443);
16003 HostPortPair alternative("www.example.org", 444);
bnc5452e2a2015-05-08 16:27:4216004
bnc8bef8da22016-05-30 01:28:2516005 // Negotiate HTTP/1.1 with alternative.
bnc5452e2a2015-05-08 16:27:4216006 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616007 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4216008 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16009
16010 // No data should be read from the alternative, because HTTP/1.1 is
16011 // negotiated.
16012 StaticSocketDataProvider data;
16013 session_deps_.socket_factory->AddSocketDataProvider(&data);
16014
16015 // This test documents that an alternate Job should not be used if HTTP/1.1 is
zhongyi3d4a55e72016-04-22 20:36:4616016 // negotiated. In order to test this, a failed connection to the server is
bnc5452e2a2015-05-08 16:27:4216017 // mocked. This way the request relies on the alternate Job.
16018 StaticSocketDataProvider data_refused;
16019 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
16020 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
16021
zhongyi3d4a55e72016-04-22 20:36:4616022 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916023 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016024 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4216025 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116026 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216027 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116028 http_server_properties->SetHttp2AlternativeService(
16029 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4216030
bnc5452e2a2015-05-08 16:27:4216031 HttpRequestInfo request;
krasinc06a72a2016-12-21 03:42:4616032 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216033 request.method = "GET";
bnc8bef8da22016-05-30 01:28:2516034 request.url = GURL("https://www.example.org:443");
Ramin Halavatib5e433e62018-02-07 07:41:1016035 request.traffic_annotation =
16036 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216037 TestCompletionCallback callback;
16038
16039 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
bnc94c92842016-09-21 15:22:5216040 // negotiated, the alternate Job should fail with ERR_ALPN_NEGOTIATION_FAILED.
tfarina42834112016-09-22 13:38:2016041 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
bnc94c92842016-09-21 15:22:5216042 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_ALPN_NEGOTIATION_FAILED));
bnc5452e2a2015-05-08 16:27:4216043}
16044
bnc40448a532015-05-11 19:13:1416045// A request to a server with an alternative service fires two Jobs: one to the
zhongyi3d4a55e72016-04-22 20:36:4616046// server, and an alternate one to the alternative server. If the former
bnc40448a532015-05-11 19:13:1416047// succeeds, the request should succeed, even if the latter fails because
16048// HTTP/1.1 is negotiated which is insufficient for alternative service.
bncd16676a2016-07-20 16:23:0116049TEST_F(HttpNetworkTransactionTest, FailedAlternativeServiceIsNotUserVisible) {
bnc8bef8da22016-05-30 01:28:2516050 url::SchemeHostPort server("https", "www.example.org", 443);
16051 HostPortPair alternative("www.example.org", 444);
bnc40448a532015-05-11 19:13:1416052
16053 // Negotiate HTTP/1.1 with alternative.
16054 SSLSocketDataProvider alternative_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616055 alternative_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1416056 session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl);
16057
16058 // No data should be read from the alternative, because HTTP/1.1 is
16059 // negotiated.
16060 StaticSocketDataProvider data;
16061 session_deps_.socket_factory->AddSocketDataProvider(&data);
16062
zhongyi3d4a55e72016-04-22 20:36:4616063 // Negotiate HTTP/1.1 with server.
bnc40448a532015-05-11 19:13:1416064 SSLSocketDataProvider origin_ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616065 origin_ssl.next_proto = kProtoHTTP11;
bnc40448a532015-05-11 19:13:1416066 session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl);
16067
16068 MockWrite http_writes[] = {
bnc8bef8da22016-05-30 01:28:2516069 MockWrite("GET / HTTP/1.1\r\n"
16070 "Host: www.example.org\r\n"
16071 "Connection: keep-alive\r\n\r\n"),
16072 MockWrite("GET /second HTTP/1.1\r\n"
16073 "Host: www.example.org\r\n"
16074 "Connection: keep-alive\r\n\r\n"),
bnc40448a532015-05-11 19:13:1416075 };
16076
16077 MockRead http_reads[] = {
16078 MockRead("HTTP/1.1 200 OK\r\n"),
16079 MockRead("Content-Type: text/html\r\n"),
16080 MockRead("Content-Length: 6\r\n\r\n"),
16081 MockRead("foobar"),
16082 MockRead("HTTP/1.1 200 OK\r\n"),
16083 MockRead("Content-Type: text/html\r\n"),
16084 MockRead("Content-Length: 7\r\n\r\n"),
16085 MockRead("another"),
16086 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116087 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc40448a532015-05-11 19:13:1416088 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16089
zhongyi3d4a55e72016-04-22 20:36:4616090 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916091 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016092 HttpServerProperties* http_server_properties =
bnc40448a532015-05-11 19:13:1416093 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116094 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216095 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116096 http_server_properties->SetHttp2AlternativeService(
16097 server, alternative_service, expiration);
bnc40448a532015-05-11 19:13:1416098
16099 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
16100 HttpRequestInfo request1;
16101 request1.method = "GET";
bnc8bef8da22016-05-30 01:28:2516102 request1.url = GURL("https://www.example.org:443");
bnc40448a532015-05-11 19:13:1416103 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016104 request1.traffic_annotation =
16105 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416106 TestCompletionCallback callback1;
16107
tfarina42834112016-09-22 13:38:2016108 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416109 rv = callback1.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116110 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416111
16112 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
wezca1070932016-05-26 20:30:5216113 ASSERT_TRUE(response1);
16114 ASSERT_TRUE(response1->headers);
bnc40448a532015-05-11 19:13:1416115 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
16116
16117 std::string response_data1;
robpercival214763f2016-07-01 23:27:0116118 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc40448a532015-05-11 19:13:1416119 EXPECT_EQ("foobar", response_data1);
16120
16121 // Alternative should be marked as broken, because HTTP/1.1 is not sufficient
16122 // for alternative service.
16123 EXPECT_TRUE(
16124 http_server_properties->IsAlternativeServiceBroken(alternative_service));
16125
zhongyi3d4a55e72016-04-22 20:36:4616126 // Since |alternative_service| is broken, a second transaction to server
bnc40448a532015-05-11 19:13:1416127 // should not start an alternate Job. It should pool to existing connection
zhongyi3d4a55e72016-04-22 20:36:4616128 // to server.
bnc40448a532015-05-11 19:13:1416129 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
16130 HttpRequestInfo request2;
16131 request2.method = "GET";
bnc8bef8da22016-05-30 01:28:2516132 request2.url = GURL("https://www.example.org:443/second");
bnc40448a532015-05-11 19:13:1416133 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016134 request2.traffic_annotation =
16135 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc40448a532015-05-11 19:13:1416136 TestCompletionCallback callback2;
16137
tfarina42834112016-09-22 13:38:2016138 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
bnc40448a532015-05-11 19:13:1416139 rv = callback2.GetResult(rv);
robpercival214763f2016-07-01 23:27:0116140 EXPECT_THAT(rv, IsOk());
bnc40448a532015-05-11 19:13:1416141
16142 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5216143 ASSERT_TRUE(response2);
16144 ASSERT_TRUE(response2->headers);
bnc40448a532015-05-11 19:13:1416145 EXPECT_EQ("HTTP/1.1 200 OK", response2->headers->GetStatusLine());
16146
16147 std::string response_data2;
robpercival214763f2016-07-01 23:27:0116148 ASSERT_THAT(ReadTransaction(&trans2, &response_data2), IsOk());
bnc40448a532015-05-11 19:13:1416149 EXPECT_EQ("another", response_data2);
16150}
16151
bnc5452e2a2015-05-08 16:27:4216152// Alternative service requires HTTP/2 (or SPDY), but there is already a
16153// HTTP/1.1 socket open to the alternative server. That socket should not be
16154// used.
bncd16676a2016-07-20 16:23:0116155TEST_F(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
zhongyi3d4a55e72016-04-22 20:36:4616156 url::SchemeHostPort server("https", "origin.example.org", 443);
bnc5452e2a2015-05-08 16:27:4216157 HostPortPair alternative("alternative.example.org", 443);
16158 std::string origin_url = "https://origin.example.org:443";
16159 std::string alternative_url = "https://alternative.example.org:443";
16160
16161 // Negotiate HTTP/1.1 with alternative.example.org.
16162 SSLSocketDataProvider ssl(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616163 ssl.next_proto = kProtoHTTP11;
bnc5452e2a2015-05-08 16:27:4216164 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
16165
16166 // HTTP/1.1 data for |request1| and |request2|.
16167 MockWrite http_writes[] = {
16168 MockWrite(
16169 "GET / HTTP/1.1\r\n"
16170 "Host: alternative.example.org\r\n"
16171 "Connection: keep-alive\r\n\r\n"),
16172 MockWrite(
16173 "GET / HTTP/1.1\r\n"
16174 "Host: alternative.example.org\r\n"
16175 "Connection: keep-alive\r\n\r\n"),
16176 };
16177
16178 MockRead http_reads[] = {
16179 MockRead(
16180 "HTTP/1.1 200 OK\r\n"
16181 "Content-Type: text/html; charset=iso-8859-1\r\n"
16182 "Content-Length: 40\r\n\r\n"
16183 "first HTTP/1.1 response from alternative"),
16184 MockRead(
16185 "HTTP/1.1 200 OK\r\n"
16186 "Content-Type: text/html; charset=iso-8859-1\r\n"
16187 "Content-Length: 41\r\n\r\n"
16188 "second HTTP/1.1 response from alternative"),
16189 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116190 StaticSocketDataProvider http_data(http_reads, http_writes);
bnc5452e2a2015-05-08 16:27:4216191 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16192
16193 // This test documents that an alternate Job should not pool to an already
16194 // existing HTTP/1.1 connection. In order to test this, a failed connection
zhongyi3d4a55e72016-04-22 20:36:4616195 // to the server is mocked. This way |request2| relies on the alternate Job.
bnc5452e2a2015-05-08 16:27:4216196 StaticSocketDataProvider data_refused;
16197 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
16198 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
16199
zhongyi3d4a55e72016-04-22 20:36:4616200 // Set up alternative service for server.
danakj1fd259a02016-04-16 03:17:0916201 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc525e175a2016-06-20 12:36:4016202 HttpServerProperties* http_server_properties =
bnc5452e2a2015-05-08 16:27:4216203 session->http_server_properties();
bnc3472afd2016-11-17 15:27:2116204 AlternativeService alternative_service(kProtoHTTP2, alternative);
bnc7dc7e1b42015-07-28 14:43:1216205 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
zhongyie537a002017-06-27 16:48:2116206 http_server_properties->SetHttp2AlternativeService(
16207 server, alternative_service, expiration);
bnc5452e2a2015-05-08 16:27:4216208
16209 // First transaction to alternative to open an HTTP/1.1 socket.
bnc5452e2a2015-05-08 16:27:4216210 HttpRequestInfo request1;
krasinc06a72a2016-12-21 03:42:4616211 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216212 request1.method = "GET";
16213 request1.url = GURL(alternative_url);
16214 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016215 request1.traffic_annotation =
16216 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216217 TestCompletionCallback callback1;
16218
tfarina42834112016-09-22 13:38:2016219 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116220 EXPECT_THAT(callback1.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616221 const HttpResponseInfo* response1 = trans1.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216222 ASSERT_TRUE(response1);
wezca1070932016-05-26 20:30:5216223 ASSERT_TRUE(response1->headers);
bnc5452e2a2015-05-08 16:27:4216224 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216225 EXPECT_TRUE(response1->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216226 EXPECT_FALSE(response1->was_fetched_via_spdy);
16227 std::string response_data1;
bnc691fda62016-08-12 00:43:1616228 ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk());
bnc5452e2a2015-05-08 16:27:4216229 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
16230
16231 // Request for origin.example.org, which has an alternative service. This
16232 // will start two Jobs: the alternative looks for connections to pool to,
16233 // finds one which is HTTP/1.1, and should ignore it, and should not try to
zhongyi3d4a55e72016-04-22 20:36:4616234 // open other connections to alternative server. The Job to server fails, so
bnc5452e2a2015-05-08 16:27:4216235 // this request fails.
bnc5452e2a2015-05-08 16:27:4216236 HttpRequestInfo request2;
krasinc06a72a2016-12-21 03:42:4616237 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216238 request2.method = "GET";
16239 request2.url = GURL(origin_url);
16240 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016241 request2.traffic_annotation =
16242 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216243 TestCompletionCallback callback2;
16244
tfarina42834112016-09-22 13:38:2016245 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116246 EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED));
bnc5452e2a2015-05-08 16:27:4216247
16248 // Another transaction to alternative. This is to test that the HTTP/1.1
16249 // socket is still open and in the pool.
bnc5452e2a2015-05-08 16:27:4216250 HttpRequestInfo request3;
krasinc06a72a2016-12-21 03:42:4616251 HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
bnc5452e2a2015-05-08 16:27:4216252 request3.method = "GET";
16253 request3.url = GURL(alternative_url);
16254 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016255 request3.traffic_annotation =
16256 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc5452e2a2015-05-08 16:27:4216257 TestCompletionCallback callback3;
16258
tfarina42834112016-09-22 13:38:2016259 rv = trans3.Start(&request3, callback3.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116260 EXPECT_THAT(callback3.GetResult(rv), IsOk());
bnc691fda62016-08-12 00:43:1616261 const HttpResponseInfo* response3 = trans3.GetResponseInfo();
bnc5452e2a2015-05-08 16:27:4216262 ASSERT_TRUE(response3);
wezca1070932016-05-26 20:30:5216263 ASSERT_TRUE(response3->headers);
bnc5452e2a2015-05-08 16:27:4216264 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
bnc94c92842016-09-21 15:22:5216265 EXPECT_TRUE(response3->was_alpn_negotiated);
bnc5452e2a2015-05-08 16:27:4216266 EXPECT_FALSE(response3->was_fetched_via_spdy);
16267 std::string response_data3;
bnc691fda62016-08-12 00:43:1616268 ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk());
bnc5452e2a2015-05-08 16:27:4216269 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
16270}
16271
bncd16676a2016-07-20 16:23:0116272TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
bncce36dca22015-04-21 22:11:2316273 const std::string https_url = "https://www.example.org:8080/";
16274 const std::string http_url = "http://www.example.org:8080/";
[email protected]8450d722012-07-02 19:14:0416275
rdsmithebb50aa2015-11-12 03:44:3816276 // Separate SPDY util instance for naked and wrapped requests.
bncd16676a2016-07-20 16:23:0116277 SpdyTestUtil spdy_util_wrapped;
rdsmithebb50aa2015-11-12 03:44:3816278
[email protected]8450d722012-07-02 19:14:0416279 // SPDY GET for HTTPS URL (through CONNECT tunnel)
bncce36dca22015-04-21 22:11:2316280 const HostPortPair host_port_pair("www.example.org", 8080);
Matt Menke6e879bd2019-03-18 17:26:0416281 spdy::SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect(
16282 nullptr, 0, 1, HttpProxyConnectJob::kH2QuicTunnelPriority,
16283 host_port_pair));
Ryan Hamilton0239aac2018-05-19 00:03:1316284 spdy::SpdySerializedFrame req1(
bnc38dcd392016-02-09 23:19:4916285 spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
Ryan Hamilton0239aac2018-05-19 00:03:1316286 spdy::SpdySerializedFrame wrapped_req1(
[email protected]23e482282013-06-14 16:08:0216287 spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
[email protected]601e03f12014-04-06 16:26:3916288
16289 // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
Ryan Hamilton0239aac2018-05-19 00:03:1316290 spdy::SpdyHeaderBlock req2_block;
16291 req2_block[spdy::kHttp2MethodHeader] = "GET";
16292 req2_block[spdy::kHttp2AuthorityHeader] = "www.example.org:8080";
16293 req2_block[spdy::kHttp2SchemeHeader] = "http";
16294 req2_block[spdy::kHttp2PathHeader] = "/";
16295 spdy::SpdySerializedFrame req2(
bnc42331402016-07-25 13:36:1516296 spdy_util_.ConstructSpdyHeaders(3, std::move(req2_block), MEDIUM, true));
[email protected]8450d722012-07-02 19:14:0416297
16298 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116299 CreateMockWrite(connect, 0), CreateMockWrite(wrapped_req1, 2),
16300 CreateMockWrite(req2, 6),
[email protected]8450d722012-07-02 19:14:0416301 };
16302
Ryan Hamilton0239aac2018-05-19 00:03:1316303 spdy::SpdySerializedFrame conn_resp(
bnc42331402016-07-25 13:36:1516304 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316305 spdy::SpdySerializedFrame resp1(
bnc42331402016-07-25 13:36:1516306 spdy_util_wrapped.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316307 spdy::SpdySerializedFrame body1(
16308 spdy_util_wrapped.ConstructSpdyDataFrame(1, true));
16309 spdy::SpdySerializedFrame wrapped_resp1(
rdsmithebb50aa2015-11-12 03:44:3816310 spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316311 spdy::SpdySerializedFrame wrapped_body1(
rdsmithebb50aa2015-11-12 03:44:3816312 spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
Raul Tambre94493c652019-03-11 17:18:3516313 spdy::SpdySerializedFrame resp2(
16314 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3));
Ryan Hamilton0239aac2018-05-19 00:03:1316315 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true));
mmenke666a6fea2015-12-19 04:16:3316316 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116317 CreateMockRead(conn_resp, 1),
mmenke666a6fea2015-12-19 04:16:3316318 MockRead(ASYNC, ERR_IO_PENDING, 3),
bncdf80d44fd2016-07-15 20:27:4116319 CreateMockRead(wrapped_resp1, 4),
16320 CreateMockRead(wrapped_body1, 5),
mmenke666a6fea2015-12-19 04:16:3316321 MockRead(ASYNC, ERR_IO_PENDING, 7),
bncdf80d44fd2016-07-15 20:27:4116322 CreateMockRead(resp2, 8),
16323 CreateMockRead(body2, 9),
mmenke666a6fea2015-12-19 04:16:3316324 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 10),
16325 };
[email protected]8450d722012-07-02 19:14:0416326
Ryan Sleevib8d7ea02018-05-07 20:01:0116327 SequencedSocketData data1(reads1, writes1);
[email protected]8450d722012-07-02 19:14:0416328 MockConnect connect_data1(ASYNC, OK);
[email protected]dd54bd82012-07-19 23:44:5716329 data1.set_connect_data(connect_data1);
[email protected]8450d722012-07-02 19:14:0416330
Lily Houghton8c2f97d2018-01-22 05:06:5916331 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4916332 ProxyResolutionService::CreateFixedFromPacResult(
16333 "HTTPS proxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
vishal.b62985ca92015-04-17 08:45:5116334 TestNetLog log;
[email protected]bb88e1d32013-05-03 23:11:0716335 session_deps_.net_log = &log;
[email protected]8450d722012-07-02 19:14:0416336 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616337 ssl1.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316338 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
[email protected]8450d722012-07-02 19:14:0416339 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616340 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316341 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16342 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]8450d722012-07-02 19:14:0416343
danakj1fd259a02016-04-16 03:17:0916344 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]8450d722012-07-02 19:14:0416345
16346 // Start the first transaction to set up the SpdySession
16347 HttpRequestInfo request1;
16348 request1.method = "GET";
16349 request1.url = GURL(https_url);
[email protected]8450d722012-07-02 19:14:0416350 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016351 request1.traffic_annotation =
16352 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016353 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]8450d722012-07-02 19:14:0416354 TestCompletionCallback callback1;
tfarina42834112016-09-22 13:38:2016355 int rv = trans1.Start(&request1, callback1.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416356
mmenke666a6fea2015-12-19 04:16:3316357 // This pause is a hack to avoid running into https://crbug.com/497228.
16358 data1.RunUntilPaused();
16359 base::RunLoop().RunUntilIdle();
16360 data1.Resume();
robpercival214763f2016-07-01 23:27:0116361 EXPECT_THAT(callback1.GetResult(rv), IsOk());
[email protected]8450d722012-07-02 19:14:0416362 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16363
[email protected]f6c63db52013-02-02 00:35:2216364 LoadTimingInfo load_timing_info1;
16365 EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
16366 TestLoadTimingNotReusedWithPac(load_timing_info1,
16367 CONNECT_TIMING_HAS_SSL_TIMES);
16368
mmenke666a6fea2015-12-19 04:16:3316369 // Now, start the HTTP request.
[email protected]8450d722012-07-02 19:14:0416370 HttpRequestInfo request2;
16371 request2.method = "GET";
16372 request2.url = GURL(http_url);
[email protected]8450d722012-07-02 19:14:0416373 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016374 request2.traffic_annotation =
16375 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016376 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]8450d722012-07-02 19:14:0416377 TestCompletionCallback callback2;
tfarina42834112016-09-22 13:38:2016378 rv = trans2.Start(&request2, callback2.callback(), NetLogWithSource());
[email protected]8450d722012-07-02 19:14:0416379
mmenke666a6fea2015-12-19 04:16:3316380 // This pause is a hack to avoid running into https://crbug.com/497228.
16381 data1.RunUntilPaused();
16382 base::RunLoop().RunUntilIdle();
16383 data1.Resume();
robpercival214763f2016-07-01 23:27:0116384 EXPECT_THAT(callback2.GetResult(rv), IsOk());
mmenke666a6fea2015-12-19 04:16:3316385
[email protected]8450d722012-07-02 19:14:0416386 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
[email protected]f6c63db52013-02-02 00:35:2216387
16388 LoadTimingInfo load_timing_info2;
16389 EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
16390 // The established SPDY sessions is considered reused by the HTTP request.
16391 TestLoadTimingReusedWithPac(load_timing_info2);
16392 // HTTP requests over a SPDY session should have a different connection
16393 // socket_log_id than requests over a tunnel.
16394 EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
[email protected]8450d722012-07-02 19:14:0416395}
16396
[email protected]2d88e7d2012-07-19 17:55:1716397// Test that in the case where we have a SPDY session to a SPDY proxy
16398// that we do not pool other origins that resolve to the same IP when
16399// the certificate does not match the new origin.
16400// http://crbug.com/134690
bncd16676a2016-07-20 16:23:0116401TEST_F(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
bncce36dca22015-04-21 22:11:2316402 const std::string url1 = "http://www.example.org/";
16403 const std::string url2 = "https://news.example.org/";
[email protected]2d88e7d2012-07-19 17:55:1716404 const std::string ip_addr = "1.2.3.4";
16405
rdsmithebb50aa2015-11-12 03:44:3816406 // Second SpdyTestUtil instance for the second socket.
bncd16676a2016-07-20 16:23:0116407 SpdyTestUtil spdy_util_secure;
rdsmithebb50aa2015-11-12 03:44:3816408
[email protected]2d88e7d2012-07-19 17:55:1716409 // SPDY GET for HTTP URL (through SPDY proxy)
Ryan Hamilton0239aac2018-05-19 00:03:1316410 spdy::SpdyHeaderBlock headers(
bncce36dca22015-04-21 22:11:2316411 spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
Ryan Hamilton0239aac2018-05-19 00:03:1316412 spdy::SpdySerializedFrame req1(
bnc42331402016-07-25 13:36:1516413 spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
[email protected]2d88e7d2012-07-19 17:55:1716414
16415 MockWrite writes1[] = {
bncdf80d44fd2016-07-15 20:27:4116416 CreateMockWrite(req1, 0),
[email protected]2d88e7d2012-07-19 17:55:1716417 };
16418
Raul Tambre94493c652019-03-11 17:18:3516419 spdy::SpdySerializedFrame resp1(
16420 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316421 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]2d88e7d2012-07-19 17:55:1716422 MockRead reads1[] = {
bncdf80d44fd2016-07-15 20:27:4116423 MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(resp1, 2),
16424 CreateMockRead(body1, 3), MockRead(ASYNC, OK, 4), // EOF
[email protected]2d88e7d2012-07-19 17:55:1716425 };
16426
Ryan Sleevib8d7ea02018-05-07 20:01:0116427 SequencedSocketData data1(reads1, writes1);
martijnfe9636e2016-02-06 14:33:3216428 IPAddress ip;
martijn654c8c42016-02-10 22:10:5916429 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
[email protected]2d88e7d2012-07-19 17:55:1716430 IPEndPoint peer_addr = IPEndPoint(ip, 443);
16431 MockConnect connect_data1(ASYNC, OK, peer_addr);
mmenke666a6fea2015-12-19 04:16:3316432 data1.set_connect_data(connect_data1);
[email protected]2d88e7d2012-07-19 17:55:1716433
16434 // SPDY GET for HTTPS URL (direct)
Ryan Hamilton0239aac2018-05-19 00:03:1316435 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916436 spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
[email protected]2d88e7d2012-07-19 17:55:1716437
16438 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116439 CreateMockWrite(req2, 0),
[email protected]2d88e7d2012-07-19 17:55:1716440 };
16441
Ryan Hamilton0239aac2018-05-19 00:03:1316442 spdy::SpdySerializedFrame resp2(
Raul Tambre94493c652019-03-11 17:18:3516443 spdy_util_secure.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316444 spdy::SpdySerializedFrame body2(
16445 spdy_util_secure.ConstructSpdyDataFrame(1, true));
bncdf80d44fd2016-07-15 20:27:4116446 MockRead reads2[] = {CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
mmenke666a6fea2015-12-19 04:16:3316447 MockRead(ASYNC, OK, 3)};
[email protected]2d88e7d2012-07-19 17:55:1716448
Ryan Sleevib8d7ea02018-05-07 20:01:0116449 SequencedSocketData data2(reads2, writes2);
[email protected]2d88e7d2012-07-19 17:55:1716450 MockConnect connect_data2(ASYNC, OK);
mmenke666a6fea2015-12-19 04:16:3316451 data2.set_connect_data(connect_data2);
[email protected]2d88e7d2012-07-19 17:55:1716452
16453 // Set up a proxy config that sends HTTP requests to a proxy, and
16454 // all others direct.
16455 ProxyConfig proxy_config;
16456 proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
Ramin Halavatica8d5252018-03-12 05:33:4916457 session_deps_.proxy_resolution_service =
16458 std::make_unique<ProxyResolutionService>(
16459 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
16460 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
16461 nullptr, nullptr);
[email protected]2d88e7d2012-07-19 17:55:1716462
bncce36dca22015-04-21 22:11:2316463 SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy
bnc3cf2a592016-08-11 14:48:3616464 ssl1.next_proto = kProtoHTTP2;
[email protected]2d88e7d2012-07-19 17:55:1716465 // Load a valid cert. Note, that this does not need to
16466 // be valid for proxy because the MockSSLClientSocket does
16467 // not actually verify it. But SpdySession will use this
16468 // to see if it is valid for the new origin
Ryan Sleevi4f832092017-11-21 23:25:4916469 ssl1.ssl_info.cert =
16470 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem");
16471 ASSERT_TRUE(ssl1.ssl_info.cert);
mmenke666a6fea2015-12-19 04:16:3316472 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16473 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]2d88e7d2012-07-19 17:55:1716474
16475 SSLSocketDataProvider ssl2(ASYNC, OK); // to the server
bnc3cf2a592016-08-11 14:48:3616476 ssl2.next_proto = kProtoHTTP2;
mmenke666a6fea2015-12-19 04:16:3316477 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16478 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]2d88e7d2012-07-19 17:55:1716479
Jeremy Roman0579ed62017-08-29 15:56:1916480 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
bncce36dca22015-04-21 22:11:2316481 session_deps_.host_resolver->rules()->AddRule("news.example.org", ip_addr);
[email protected]bb88e1d32013-05-03 23:11:0716482 session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
[email protected]2d88e7d2012-07-19 17:55:1716483
danakj1fd259a02016-04-16 03:17:0916484 std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_);
[email protected]2d88e7d2012-07-19 17:55:1716485
16486 // Start the first transaction to set up the SpdySession
16487 HttpRequestInfo request1;
16488 request1.method = "GET";
16489 request1.url = GURL(url1);
[email protected]2d88e7d2012-07-19 17:55:1716490 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016491 request1.traffic_annotation =
16492 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016493 HttpNetworkTransaction trans1(LOWEST, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716494 TestCompletionCallback callback1;
16495 ASSERT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016496 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
mmenke666a6fea2015-12-19 04:16:3316497 // This pause is a hack to avoid running into https://crbug.com/497228.
16498 data1.RunUntilPaused();
16499 base::RunLoop().RunUntilIdle();
16500 data1.Resume();
[email protected]2d88e7d2012-07-19 17:55:1716501
robpercival214763f2016-07-01 23:27:0116502 EXPECT_THAT(callback1.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716503 EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
16504
16505 // Now, start the HTTP request
16506 HttpRequestInfo request2;
16507 request2.method = "GET";
16508 request2.url = GURL(url2);
[email protected]2d88e7d2012-07-19 17:55:1716509 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016510 request2.traffic_annotation =
16511 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016512 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]2d88e7d2012-07-19 17:55:1716513 TestCompletionCallback callback2;
16514 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016515 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
fdoray92e35a72016-06-10 15:54:5516516 base::RunLoop().RunUntilIdle();
[email protected]2d88e7d2012-07-19 17:55:1716517
16518 ASSERT_TRUE(callback2.have_result());
robpercival214763f2016-07-01 23:27:0116519 EXPECT_THAT(callback2.WaitForResult(), IsOk());
[email protected]2d88e7d2012-07-19 17:55:1716520 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16521}
16522
[email protected]85f97342013-04-17 06:12:2416523// Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
16524// error) in SPDY session, removes the socket from pool and closes the SPDY
16525// session. Verify that new url's from the same HttpNetworkSession (and a new
16526// SpdySession) do work. http://crbug.com/224701
bncd16676a2016-07-20 16:23:0116527TEST_F(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
bncce36dca22015-04-21 22:11:2316528 const std::string https_url = "https://www.example.org/";
[email protected]85f97342013-04-17 06:12:2416529
16530 MockRead reads1[] = {
16531 MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
16532 };
16533
Ryan Sleevib8d7ea02018-05-07 20:01:0116534 SequencedSocketData data1(reads1, base::span<MockWrite>());
[email protected]85f97342013-04-17 06:12:2416535
Ryan Hamilton0239aac2018-05-19 00:03:1316536 spdy::SpdySerializedFrame req2(
bnc38dcd392016-02-09 23:19:4916537 spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
[email protected]85f97342013-04-17 06:12:2416538 MockWrite writes2[] = {
bncdf80d44fd2016-07-15 20:27:4116539 CreateMockWrite(req2, 0),
[email protected]85f97342013-04-17 06:12:2416540 };
16541
Raul Tambre94493c652019-03-11 17:18:3516542 spdy::SpdySerializedFrame resp2(
16543 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316544 spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]85f97342013-04-17 06:12:2416545 MockRead reads2[] = {
bncdf80d44fd2016-07-15 20:27:4116546 CreateMockRead(resp2, 1), CreateMockRead(body2, 2),
16547 MockRead(ASYNC, OK, 3) // EOF
[email protected]85f97342013-04-17 06:12:2416548 };
16549
Ryan Sleevib8d7ea02018-05-07 20:01:0116550 SequencedSocketData data2(reads2, writes2);
[email protected]85f97342013-04-17 06:12:2416551
[email protected]85f97342013-04-17 06:12:2416552 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616553 ssl1.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016554 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16555 session_deps_.socket_factory->AddSocketDataProvider(&data1);
[email protected]85f97342013-04-17 06:12:2416556
16557 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616558 ssl2.next_proto = kProtoHTTP2;
mmenke11eb5152015-06-09 14:50:5016559 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16560 session_deps_.socket_factory->AddSocketDataProvider(&data2);
[email protected]85f97342013-04-17 06:12:2416561
danakj1fd259a02016-04-16 03:17:0916562 std::unique_ptr<HttpNetworkSession> session(
mmenke11eb5152015-06-09 14:50:5016563 SpdySessionDependencies::SpdyCreateSession(&session_deps_));
[email protected]85f97342013-04-17 06:12:2416564
16565 // Start the first transaction to set up the SpdySession and verify that
16566 // connection was closed.
16567 HttpRequestInfo request1;
16568 request1.method = "GET";
16569 request1.url = GURL(https_url);
16570 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016571 request1.traffic_annotation =
16572 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016573 HttpNetworkTransaction trans1(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416574 TestCompletionCallback callback1;
16575 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016576 trans1.Start(&request1, callback1.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0116577 EXPECT_THAT(callback1.WaitForResult(), IsError(ERR_CONNECTION_CLOSED));
[email protected]85f97342013-04-17 06:12:2416578
16579 // Now, start the second request and make sure it succeeds.
16580 HttpRequestInfo request2;
16581 request2.method = "GET";
16582 request2.url = GURL(https_url);
16583 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016584 request2.traffic_annotation =
16585 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]90499482013-06-01 00:39:5016586 HttpNetworkTransaction trans2(MEDIUM, session.get());
[email protected]85f97342013-04-17 06:12:2416587 TestCompletionCallback callback2;
16588 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2016589 trans2.Start(&request2, callback2.callback(), NetLogWithSource()));
[email protected]85f97342013-04-17 06:12:2416590
robpercival214763f2016-07-01 23:27:0116591 ASSERT_THAT(callback2.WaitForResult(), IsOk());
[email protected]85f97342013-04-17 06:12:2416592 EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
16593}
16594
bncd16676a2016-07-20 16:23:0116595TEST_F(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
[email protected]483fa202013-05-14 01:07:0316596 ClientSocketPoolManager::set_max_sockets_per_group(
16597 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16598 ClientSocketPoolManager::set_max_sockets_per_pool(
16599 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
16600
16601 // Use two different hosts with different IPs so they don't get pooled.
16602 session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
16603 session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
danakj1fd259a02016-04-16 03:17:0916604 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]483fa202013-05-14 01:07:0316605
16606 SSLSocketDataProvider ssl1(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616607 ssl1.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316608 SSLSocketDataProvider ssl2(ASYNC, OK);
bnc3cf2a592016-08-11 14:48:3616609 ssl2.next_proto = kProtoHTTP2;
[email protected]483fa202013-05-14 01:07:0316610 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
16611 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
16612
Ryan Hamilton0239aac2018-05-19 00:03:1316613 spdy::SpdySerializedFrame host1_req(
bnc38dcd392016-02-09 23:19:4916614 spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316615 MockWrite spdy1_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116616 CreateMockWrite(host1_req, 0),
[email protected]483fa202013-05-14 01:07:0316617 };
Ryan Hamilton0239aac2018-05-19 00:03:1316618 spdy::SpdySerializedFrame host1_resp(
Raul Tambre94493c652019-03-11 17:18:3516619 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316620 spdy::SpdySerializedFrame host1_resp_body(
bncdf80d44fd2016-07-15 20:27:4116621 spdy_util_.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316622 MockRead spdy1_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116623 CreateMockRead(host1_resp, 1), CreateMockRead(host1_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916624 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316625 };
16626
rdsmithebb50aa2015-11-12 03:44:3816627 // Use a separate test instance for the separate SpdySession that will be
16628 // created.
bncd16676a2016-07-20 16:23:0116629 SpdyTestUtil spdy_util_2;
Ryan Sleevib8d7ea02018-05-07 20:01:0116630 SequencedSocketData spdy1_data(spdy1_reads, spdy1_writes);
Bence Béky53a5aef2018-03-29 21:54:1216631 session_deps_.socket_factory->AddSocketDataProvider(&spdy1_data);
[email protected]483fa202013-05-14 01:07:0316632
Ryan Hamilton0239aac2018-05-19 00:03:1316633 spdy::SpdySerializedFrame host2_req(
bnc38dcd392016-02-09 23:19:4916634 spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
[email protected]483fa202013-05-14 01:07:0316635 MockWrite spdy2_writes[] = {
bncdf80d44fd2016-07-15 20:27:4116636 CreateMockWrite(host2_req, 0),
[email protected]483fa202013-05-14 01:07:0316637 };
Ryan Hamilton0239aac2018-05-19 00:03:1316638 spdy::SpdySerializedFrame host2_resp(
Raul Tambre94493c652019-03-11 17:18:3516639 spdy_util_2.ConstructSpdyGetReply(nullptr, 0, 1));
Ryan Hamilton0239aac2018-05-19 00:03:1316640 spdy::SpdySerializedFrame host2_resp_body(
bncdf80d44fd2016-07-15 20:27:4116641 spdy_util_2.ConstructSpdyDataFrame(1, true));
[email protected]483fa202013-05-14 01:07:0316642 MockRead spdy2_reads[] = {
bncdf80d44fd2016-07-15 20:27:4116643 CreateMockRead(host2_resp, 1), CreateMockRead(host2_resp_body, 2),
mmenkee24011922015-12-17 22:12:5916644 MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3),
[email protected]483fa202013-05-14 01:07:0316645 };
16646
Ryan Sleevib8d7ea02018-05-07 20:01:0116647 SequencedSocketData spdy2_data(spdy2_reads, spdy2_writes);
Bence Béky53a5aef2018-03-29 21:54:1216648 session_deps_.socket_factory->AddSocketDataProvider(&spdy2_data);
[email protected]483fa202013-05-14 01:07:0316649
16650 MockWrite http_write[] = {
16651 MockWrite("GET / HTTP/1.1\r\n"
16652 "Host: www.a.com\r\n"
16653 "Connection: keep-alive\r\n\r\n"),
16654 };
16655
16656 MockRead http_read[] = {
16657 MockRead("HTTP/1.1 200 OK\r\n"),
16658 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
16659 MockRead("Content-Length: 6\r\n\r\n"),
16660 MockRead("hello!"),
16661 };
Ryan Sleevib8d7ea02018-05-07 20:01:0116662 StaticSocketDataProvider http_data(http_read, http_write);
[email protected]483fa202013-05-14 01:07:0316663 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
16664
16665 HostPortPair host_port_pair_a("www.a.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116666 SpdySessionKey spdy_session_key_a(
16667 host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16668 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316669 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616670 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316671
16672 TestCompletionCallback callback;
16673 HttpRequestInfo request1;
16674 request1.method = "GET";
16675 request1.url = GURL("https://www.a.com/");
16676 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016677 request1.traffic_annotation =
16678 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816679 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1916680 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316681
tfarina42834112016-09-22 13:38:2016682 int rv = trans->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116683 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16684 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316685
16686 const HttpResponseInfo* response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216687 ASSERT_TRUE(response);
16688 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216689 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316690 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216691 EXPECT_TRUE(response->was_alpn_negotiated);
[email protected]483fa202013-05-14 01:07:0316692
16693 std::string response_data;
robpercival214763f2016-07-01 23:27:0116694 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316695 EXPECT_EQ("hello!", response_data);
16696 trans.reset();
16697 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616698 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316699
16700 HostPortPair host_port_pair_b("www.b.com", 443);
Matt Menke2436b2f2018-12-11 18:07:1116701 SpdySessionKey spdy_session_key_b(
16702 host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16703 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316704 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616705 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316706 HttpRequestInfo request2;
16707 request2.method = "GET";
16708 request2.url = GURL("https://www.b.com/");
16709 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016710 request2.traffic_annotation =
16711 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816712 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916713 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316714
tfarina42834112016-09-22 13:38:2016715 rv = trans->Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116716 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16717 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316718
16719 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216720 ASSERT_TRUE(response);
16721 ASSERT_TRUE(response->headers);
bnc84e7fb52015-12-02 11:50:0216722 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
[email protected]483fa202013-05-14 01:07:0316723 EXPECT_TRUE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216724 EXPECT_TRUE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116725 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316726 EXPECT_EQ("hello!", response_data);
16727 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616728 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316729 EXPECT_TRUE(
[email protected]41d64e82013-07-03 22:44:2616730 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316731
16732 HostPortPair host_port_pair_a1("www.a.com", 80);
Matt Menke2436b2f2018-12-11 18:07:1116733 SpdySessionKey spdy_session_key_a1(
16734 host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED,
16735 SpdySessionKey::IsProxySession::kFalse, SocketTag());
[email protected]483fa202013-05-14 01:07:0316736 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616737 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
[email protected]483fa202013-05-14 01:07:0316738 HttpRequestInfo request3;
16739 request3.method = "GET";
16740 request3.url = GURL("http://www.a.com/");
16741 request3.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1016742 request3.traffic_annotation =
16743 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
bnc87dcefc2017-05-25 12:47:5816744 trans =
Jeremy Roman0579ed62017-08-29 15:56:1916745 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
[email protected]483fa202013-05-14 01:07:0316746
tfarina42834112016-09-22 13:38:2016747 rv = trans->Start(&request3, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116748 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
16749 EXPECT_THAT(callback.WaitForResult(), IsOk());
[email protected]483fa202013-05-14 01:07:0316750
16751 response = trans->GetResponseInfo();
wezca1070932016-05-26 20:30:5216752 ASSERT_TRUE(response);
16753 ASSERT_TRUE(response->headers);
[email protected]483fa202013-05-14 01:07:0316754 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
16755 EXPECT_FALSE(response->was_fetched_via_spdy);
bnc94c92842016-09-21 15:22:5216756 EXPECT_FALSE(response->was_alpn_negotiated);
robpercival214763f2016-07-01 23:27:0116757 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
[email protected]483fa202013-05-14 01:07:0316758 EXPECT_EQ("hello!", response_data);
16759 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616760 HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
[email protected]483fa202013-05-14 01:07:0316761 EXPECT_FALSE(
[email protected]41d64e82013-07-03 22:44:2616762 HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
[email protected]483fa202013-05-14 01:07:0316763}
16764
bncd16676a2016-07-20 16:23:0116765TEST_F(HttpNetworkTransactionTest, HttpSyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416766 HttpRequestInfo request;
16767 request.method = "GET";
bncce36dca22015-04-21 22:11:2316768 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016769 request.traffic_annotation =
16770 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416771
danakj1fd259a02016-04-16 03:17:0916772 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616773 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416774
ttuttled9dbc652015-09-29 20:00:5916775 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416776 StaticSocketDataProvider data;
16777 data.set_connect_data(mock_connect);
16778 session_deps_.socket_factory->AddSocketDataProvider(&data);
16779
16780 TestCompletionCallback callback;
16781
tfarina42834112016-09-22 13:38:2016782 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116783 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416784
16785 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116786 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416787
[email protected]79e1fd62013-06-20 06:50:0416788 // We don't care whether this succeeds or fails, but it shouldn't crash.
16789 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616790 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716791
16792 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616793 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716794 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116795 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916796
16797 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616798 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916799 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416800}
16801
bncd16676a2016-07-20 16:23:0116802TEST_F(HttpNetworkTransactionTest, HttpAsyncConnectError) {
[email protected]79e1fd62013-06-20 06:50:0416803 HttpRequestInfo request;
16804 request.method = "GET";
bncce36dca22015-04-21 22:11:2316805 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016806 request.traffic_annotation =
16807 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416808
danakj1fd259a02016-04-16 03:17:0916809 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616810 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416811
ttuttled9dbc652015-09-29 20:00:5916812 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
[email protected]79e1fd62013-06-20 06:50:0416813 StaticSocketDataProvider data;
16814 data.set_connect_data(mock_connect);
16815 session_deps_.socket_factory->AddSocketDataProvider(&data);
16816
16817 TestCompletionCallback callback;
16818
tfarina42834112016-09-22 13:38:2016819 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116820 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416821
16822 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116823 EXPECT_THAT(rv, IsError(ERR_NAME_NOT_RESOLVED));
[email protected]79e1fd62013-06-20 06:50:0416824
[email protected]79e1fd62013-06-20 06:50:0416825 // We don't care whether this succeeds or fails, but it shouldn't crash.
16826 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616827 trans.GetFullRequestHeaders(&request_headers);
ttuttle1f2d7e92015-04-28 16:17:4716828
16829 ConnectionAttempts attempts;
bnc691fda62016-08-12 00:43:1616830 trans.GetConnectionAttempts(&attempts);
ttuttle1f2d7e92015-04-28 16:17:4716831 ASSERT_EQ(1u, attempts.size());
robpercival214763f2016-07-01 23:27:0116832 EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED));
ttuttled9dbc652015-09-29 20:00:5916833
16834 IPEndPoint endpoint;
bnc691fda62016-08-12 00:43:1616835 EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint));
ttuttled9dbc652015-09-29 20:00:5916836 EXPECT_TRUE(endpoint.address().empty());
[email protected]79e1fd62013-06-20 06:50:0416837}
16838
bncd16676a2016-07-20 16:23:0116839TEST_F(HttpNetworkTransactionTest, HttpSyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416840 HttpRequestInfo request;
16841 request.method = "GET";
bncce36dca22015-04-21 22:11:2316842 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016843 request.traffic_annotation =
16844 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416845
danakj1fd259a02016-04-16 03:17:0916846 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616847 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416848
16849 MockWrite data_writes[] = {
16850 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
16851 };
16852 MockRead data_reads[] = {
16853 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16854 };
16855
Ryan Sleevib8d7ea02018-05-07 20:01:0116856 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416857 session_deps_.socket_factory->AddSocketDataProvider(&data);
16858
16859 TestCompletionCallback callback;
16860
tfarina42834112016-09-22 13:38:2016861 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116862 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416863
16864 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116865 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416866
[email protected]79e1fd62013-06-20 06:50:0416867 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616868 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416869 EXPECT_TRUE(request_headers.HasHeader("Host"));
16870}
16871
bncd16676a2016-07-20 16:23:0116872TEST_F(HttpNetworkTransactionTest, HttpAsyncWriteError) {
[email protected]79e1fd62013-06-20 06:50:0416873 HttpRequestInfo request;
16874 request.method = "GET";
bncce36dca22015-04-21 22:11:2316875 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016876 request.traffic_annotation =
16877 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416878
danakj1fd259a02016-04-16 03:17:0916879 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616880 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416881
16882 MockWrite data_writes[] = {
16883 MockWrite(ASYNC, ERR_CONNECTION_RESET),
16884 };
16885 MockRead data_reads[] = {
16886 MockRead(SYNCHRONOUS, ERR_UNEXPECTED), // Should not be reached.
16887 };
16888
Ryan Sleevib8d7ea02018-05-07 20:01:0116889 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416890 session_deps_.socket_factory->AddSocketDataProvider(&data);
16891
16892 TestCompletionCallback callback;
16893
tfarina42834112016-09-22 13:38:2016894 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116895 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416896
16897 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116898 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416899
[email protected]79e1fd62013-06-20 06:50:0416900 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616901 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416902 EXPECT_TRUE(request_headers.HasHeader("Host"));
16903}
16904
bncd16676a2016-07-20 16:23:0116905TEST_F(HttpNetworkTransactionTest, HttpSyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416906 HttpRequestInfo request;
16907 request.method = "GET";
bncce36dca22015-04-21 22:11:2316908 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016909 request.traffic_annotation =
16910 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416911
danakj1fd259a02016-04-16 03:17:0916912 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616913 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416914
16915 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316916 MockWrite(
16917 "GET / HTTP/1.1\r\n"
16918 "Host: www.example.org\r\n"
16919 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416920 };
16921 MockRead data_reads[] = {
16922 MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
16923 };
16924
Ryan Sleevib8d7ea02018-05-07 20:01:0116925 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416926 session_deps_.socket_factory->AddSocketDataProvider(&data);
16927
16928 TestCompletionCallback callback;
16929
tfarina42834112016-09-22 13:38:2016930 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116931 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416932
16933 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116934 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416935
[email protected]79e1fd62013-06-20 06:50:0416936 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616937 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416938 EXPECT_TRUE(request_headers.HasHeader("Host"));
16939}
16940
bncd16676a2016-07-20 16:23:0116941TEST_F(HttpNetworkTransactionTest, HttpAsyncReadError) {
[email protected]79e1fd62013-06-20 06:50:0416942 HttpRequestInfo request;
16943 request.method = "GET";
bncce36dca22015-04-21 22:11:2316944 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1016945 request.traffic_annotation =
16946 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416947
danakj1fd259a02016-04-16 03:17:0916948 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616949 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416950
16951 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316952 MockWrite(
16953 "GET / HTTP/1.1\r\n"
16954 "Host: www.example.org\r\n"
16955 "Connection: keep-alive\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416956 };
16957 MockRead data_reads[] = {
16958 MockRead(ASYNC, ERR_CONNECTION_RESET),
16959 };
16960
Ryan Sleevib8d7ea02018-05-07 20:01:0116961 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0416962 session_deps_.socket_factory->AddSocketDataProvider(&data);
16963
16964 TestCompletionCallback callback;
16965
tfarina42834112016-09-22 13:38:2016966 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0116967 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0416968
16969 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0116970 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]79e1fd62013-06-20 06:50:0416971
[email protected]79e1fd62013-06-20 06:50:0416972 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1616973 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0416974 EXPECT_TRUE(request_headers.HasHeader("Host"));
16975}
16976
bncd16676a2016-07-20 16:23:0116977TEST_F(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
[email protected]79e1fd62013-06-20 06:50:0416978 HttpRequestInfo request;
16979 request.method = "GET";
bncce36dca22015-04-21 22:11:2316980 request.url = GURL("http://www.example.org/");
[email protected]79e1fd62013-06-20 06:50:0416981 request.extra_headers.SetHeader("X-Foo", "bar");
Ramin Halavatib5e433e62018-02-07 07:41:1016982 request.traffic_annotation =
16983 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]79e1fd62013-06-20 06:50:0416984
danakj1fd259a02016-04-16 03:17:0916985 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1616986 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]79e1fd62013-06-20 06:50:0416987
16988 MockWrite data_writes[] = {
bncce36dca22015-04-21 22:11:2316989 MockWrite(
16990 "GET / HTTP/1.1\r\n"
16991 "Host: www.example.org\r\n"
16992 "Connection: keep-alive\r\n"
16993 "X-Foo: bar\r\n\r\n"),
[email protected]79e1fd62013-06-20 06:50:0416994 };
16995 MockRead data_reads[] = {
16996 MockRead("HTTP/1.1 200 OK\r\n"
16997 "Content-Length: 5\r\n\r\n"
16998 "hello"),
16999 MockRead(ASYNC, ERR_UNEXPECTED),
17000 };
17001
Ryan Sleevib8d7ea02018-05-07 20:01:0117002 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]79e1fd62013-06-20 06:50:0417003 session_deps_.socket_factory->AddSocketDataProvider(&data);
17004
17005 TestCompletionCallback callback;
17006
tfarina42834112016-09-22 13:38:2017007 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117008 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]79e1fd62013-06-20 06:50:0417009
17010 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117011 EXPECT_THAT(rv, IsOk());
[email protected]79e1fd62013-06-20 06:50:0417012
17013 HttpRequestHeaders request_headers;
bnc691fda62016-08-12 00:43:1617014 EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers));
[email protected]79e1fd62013-06-20 06:50:0417015 std::string foo;
17016 EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
17017 EXPECT_EQ("bar", foo);
17018}
17019
[email protected]043b68c82013-08-22 23:41:5217020// Tests that when a used socket is returned to the SSL socket pool, it's closed
17021// if the transport socket pool is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0117022TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
[email protected]043b68c82013-08-22 23:41:5217023 ClientSocketPoolManager::set_max_sockets_per_group(
17024 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17025 ClientSocketPoolManager::set_max_sockets_per_pool(
17026 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17027
17028 // Set up SSL request.
17029
17030 HttpRequestInfo ssl_request;
17031 ssl_request.method = "GET";
bncce36dca22015-04-21 22:11:2317032 ssl_request.url = GURL("https://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017033 ssl_request.traffic_annotation =
17034 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217035
17036 MockWrite ssl_writes[] = {
bncce36dca22015-04-21 22:11:2317037 MockWrite(
17038 "GET / HTTP/1.1\r\n"
17039 "Host: www.example.org\r\n"
17040 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217041 };
17042 MockRead ssl_reads[] = {
17043 MockRead("HTTP/1.1 200 OK\r\n"),
17044 MockRead("Content-Length: 11\r\n\r\n"),
17045 MockRead("hello world"),
17046 MockRead(SYNCHRONOUS, OK),
17047 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117048 StaticSocketDataProvider ssl_data(ssl_reads, ssl_writes);
[email protected]043b68c82013-08-22 23:41:5217049 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
17050
17051 SSLSocketDataProvider ssl(ASYNC, OK);
17052 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17053
17054 // Set up HTTP request.
17055
17056 HttpRequestInfo http_request;
17057 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2317058 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017059 http_request.traffic_annotation =
17060 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217061
17062 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2317063 MockWrite(
17064 "GET / HTTP/1.1\r\n"
17065 "Host: www.example.org\r\n"
17066 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217067 };
17068 MockRead http_reads[] = {
17069 MockRead("HTTP/1.1 200 OK\r\n"),
17070 MockRead("Content-Length: 7\r\n\r\n"),
17071 MockRead("falafel"),
17072 MockRead(SYNCHRONOUS, OK),
17073 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117074 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5217075 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17076
danakj1fd259a02016-04-16 03:17:0917077 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5217078
17079 // Start the SSL request.
17080 TestCompletionCallback ssl_callback;
bnc691fda62016-08-12 00:43:1617081 HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017082 ASSERT_EQ(ERR_IO_PENDING,
17083 ssl_trans.Start(&ssl_request, ssl_callback.callback(),
17084 NetLogWithSource()));
[email protected]043b68c82013-08-22 23:41:5217085
17086 // Start the HTTP request. Pool should stall.
17087 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617088 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017089 ASSERT_EQ(ERR_IO_PENDING,
17090 http_trans.Start(&http_request, http_callback.callback(),
17091 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117092 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217093
17094 // Wait for response from SSL request.
robpercival214763f2016-07-01 23:27:0117095 ASSERT_THAT(ssl_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217096 std::string response_data;
bnc691fda62016-08-12 00:43:1617097 ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217098 EXPECT_EQ("hello world", response_data);
17099
17100 // The SSL socket should automatically be closed, so the HTTP request can
17101 // start.
Matt Menke9d5e2c92019-02-05 01:42:2317102 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
dcheng48459ac22014-08-26 00:46:4117103 ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217104
17105 // The HTTP request can now complete.
robpercival214763f2016-07-01 23:27:0117106 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
bnc691fda62016-08-12 00:43:1617107 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217108 EXPECT_EQ("falafel", response_data);
17109
dcheng48459ac22014-08-26 00:46:4117110 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217111}
17112
17113// Tests that when a SSL connection is established but there's no corresponding
17114// request that needs it, the new socket is closed if the transport socket pool
17115// is stalled on the global socket limit.
bncd16676a2016-07-20 16:23:0117116TEST_F(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
[email protected]043b68c82013-08-22 23:41:5217117 ClientSocketPoolManager::set_max_sockets_per_group(
17118 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17119 ClientSocketPoolManager::set_max_sockets_per_pool(
17120 HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
17121
17122 // Set up an ssl request.
17123
17124 HttpRequestInfo ssl_request;
17125 ssl_request.method = "GET";
17126 ssl_request.url = GURL("https://www.foopy.com/");
Ramin Halavatib5e433e62018-02-07 07:41:1017127 ssl_request.traffic_annotation =
17128 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217129
17130 // No data will be sent on the SSL socket.
17131 StaticSocketDataProvider ssl_data;
17132 session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
17133
17134 SSLSocketDataProvider ssl(ASYNC, OK);
17135 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17136
17137 // Set up HTTP request.
17138
17139 HttpRequestInfo http_request;
17140 http_request.method = "GET";
bncce36dca22015-04-21 22:11:2317141 http_request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017142 http_request.traffic_annotation =
17143 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]043b68c82013-08-22 23:41:5217144
17145 MockWrite http_writes[] = {
bncce36dca22015-04-21 22:11:2317146 MockWrite(
17147 "GET / HTTP/1.1\r\n"
17148 "Host: www.example.org\r\n"
17149 "Connection: keep-alive\r\n\r\n"),
[email protected]043b68c82013-08-22 23:41:5217150 };
17151 MockRead http_reads[] = {
17152 MockRead("HTTP/1.1 200 OK\r\n"),
17153 MockRead("Content-Length: 7\r\n\r\n"),
17154 MockRead("falafel"),
17155 MockRead(SYNCHRONOUS, OK),
17156 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117157 StaticSocketDataProvider http_data(http_reads, http_writes);
[email protected]043b68c82013-08-22 23:41:5217158 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
17159
danakj1fd259a02016-04-16 03:17:0917160 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]043b68c82013-08-22 23:41:5217161
17162 // Preconnect an SSL socket. A preconnect is needed because connect jobs are
17163 // cancelled when a normal transaction is cancelled.
ttuttle859dc7a2015-04-23 19:42:2917164 HttpStreamFactory* http_stream_factory = session->http_stream_factory();
nharper8cdb0fb2016-04-22 21:34:5917165 http_stream_factory->PreconnectStreams(1, ssl_request);
Matt Menke9d5e2c92019-02-05 01:42:2317166 EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217167
17168 // Start the HTTP request. Pool should stall.
17169 TestCompletionCallback http_callback;
bnc691fda62016-08-12 00:43:1617170 HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017171 ASSERT_EQ(ERR_IO_PENDING,
17172 http_trans.Start(&http_request, http_callback.callback(),
17173 NetLogWithSource()));
dcheng48459ac22014-08-26 00:46:4117174 EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
[email protected]043b68c82013-08-22 23:41:5217175
17176 // The SSL connection will automatically be closed once the connection is
17177 // established, to let the HTTP request start.
robpercival214763f2016-07-01 23:27:0117178 ASSERT_THAT(http_callback.WaitForResult(), IsOk());
[email protected]043b68c82013-08-22 23:41:5217179 std::string response_data;
bnc691fda62016-08-12 00:43:1617180 ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk());
[email protected]043b68c82013-08-22 23:41:5217181 EXPECT_EQ("falafel", response_data);
17182
dcheng48459ac22014-08-26 00:46:4117183 EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
[email protected]043b68c82013-08-22 23:41:5217184}
17185
bncd16676a2016-07-20 16:23:0117186TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917187 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217188 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917189 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217190 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417191
17192 HttpRequestInfo request;
17193 request.method = "POST";
17194 request.url = GURL("http://www.foo.com/");
17195 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017196 request.traffic_annotation =
17197 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417198
danakj1fd259a02016-04-16 03:17:0917199 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617200 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417201 // Send headers successfully, but get an error while sending the body.
17202 MockWrite data_writes[] = {
17203 MockWrite("POST / HTTP/1.1\r\n"
17204 "Host: www.foo.com\r\n"
17205 "Connection: keep-alive\r\n"
17206 "Content-Length: 3\r\n\r\n"),
17207 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17208 };
17209
17210 MockRead data_reads[] = {
17211 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17212 MockRead("hello world"),
17213 MockRead(SYNCHRONOUS, OK),
17214 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117215 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417216 session_deps_.socket_factory->AddSocketDataProvider(&data);
17217
17218 TestCompletionCallback callback;
17219
tfarina42834112016-09-22 13:38:2017220 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117221 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417222
17223 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117224 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417225
bnc691fda62016-08-12 00:43:1617226 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217227 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417228
wezca1070932016-05-26 20:30:5217229 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417230 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17231
17232 std::string response_data;
bnc691fda62016-08-12 00:43:1617233 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117234 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417235 EXPECT_EQ("hello world", response_data);
17236}
17237
17238// This test makes sure the retry logic doesn't trigger when reading an error
17239// response from a server that rejected a POST with a CONNECTION_RESET.
bncd16676a2016-07-20 16:23:0117240TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417241 PostReadsErrorResponseAfterResetOnReusedSocket) {
danakj1fd259a02016-04-16 03:17:0917242 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
[email protected]02d74a02014-04-23 18:10:5417243 MockWrite data_writes[] = {
17244 MockWrite("GET / HTTP/1.1\r\n"
17245 "Host: www.foo.com\r\n"
17246 "Connection: keep-alive\r\n\r\n"),
17247 MockWrite("POST / HTTP/1.1\r\n"
17248 "Host: www.foo.com\r\n"
17249 "Connection: keep-alive\r\n"
17250 "Content-Length: 3\r\n\r\n"),
17251 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17252 };
17253
17254 MockRead data_reads[] = {
17255 MockRead("HTTP/1.1 200 Peachy\r\n"
17256 "Content-Length: 14\r\n\r\n"),
17257 MockRead("first response"),
17258 MockRead("HTTP/1.1 400 Not OK\r\n"
17259 "Content-Length: 15\r\n\r\n"),
17260 MockRead("second response"),
17261 MockRead(SYNCHRONOUS, OK),
17262 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117263 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417264 session_deps_.socket_factory->AddSocketDataProvider(&data);
17265
17266 TestCompletionCallback callback;
17267 HttpRequestInfo request1;
17268 request1.method = "GET";
17269 request1.url = GURL("http://www.foo.com/");
17270 request1.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1017271 request1.traffic_annotation =
17272 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417273
bnc87dcefc2017-05-25 12:47:5817274 auto trans1 =
Jeremy Roman0579ed62017-08-29 15:56:1917275 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017276 int rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117277 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417278
17279 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117280 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417281
17282 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
wezca1070932016-05-26 20:30:5217283 ASSERT_TRUE(response1);
[email protected]02d74a02014-04-23 18:10:5417284
wezca1070932016-05-26 20:30:5217285 EXPECT_TRUE(response1->headers);
[email protected]02d74a02014-04-23 18:10:5417286 EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
17287
17288 std::string response_data1;
17289 rv = ReadTransaction(trans1.get(), &response_data1);
robpercival214763f2016-07-01 23:27:0117290 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417291 EXPECT_EQ("first response", response_data1);
17292 // Delete the transaction to release the socket back into the socket pool.
17293 trans1.reset();
17294
danakj1fd259a02016-04-16 03:17:0917295 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217296 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917297 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217298 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417299
17300 HttpRequestInfo request2;
17301 request2.method = "POST";
17302 request2.url = GURL("http://www.foo.com/");
17303 request2.upload_data_stream = &upload_data_stream;
17304 request2.load_flags = 0;
Ramin Halavatib5e433e62018-02-07 07:41:1017305 request2.traffic_annotation =
17306 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417307
bnc691fda62016-08-12 00:43:1617308 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
tfarina42834112016-09-22 13:38:2017309 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117310 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417311
17312 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117313 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417314
bnc691fda62016-08-12 00:43:1617315 const HttpResponseInfo* response2 = trans2.GetResponseInfo();
wezca1070932016-05-26 20:30:5217316 ASSERT_TRUE(response2);
[email protected]02d74a02014-04-23 18:10:5417317
wezca1070932016-05-26 20:30:5217318 EXPECT_TRUE(response2->headers);
[email protected]02d74a02014-04-23 18:10:5417319 EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
17320
17321 std::string response_data2;
bnc691fda62016-08-12 00:43:1617322 rv = ReadTransaction(&trans2, &response_data2);
robpercival214763f2016-07-01 23:27:0117323 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417324 EXPECT_EQ("second response", response_data2);
17325}
17326
bncd16676a2016-07-20 16:23:0117327TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417328 PostReadsErrorResponseAfterResetPartialBodySent) {
danakj1fd259a02016-04-16 03:17:0917329 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217330 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917331 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217332 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417333
17334 HttpRequestInfo request;
17335 request.method = "POST";
17336 request.url = GURL("http://www.foo.com/");
17337 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017338 request.traffic_annotation =
17339 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417340
danakj1fd259a02016-04-16 03:17:0917341 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617342 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417343 // Send headers successfully, but get an error while sending the body.
17344 MockWrite data_writes[] = {
17345 MockWrite("POST / HTTP/1.1\r\n"
17346 "Host: www.foo.com\r\n"
17347 "Connection: keep-alive\r\n"
17348 "Content-Length: 3\r\n\r\n"
17349 "fo"),
17350 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17351 };
17352
17353 MockRead data_reads[] = {
17354 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17355 MockRead("hello world"),
17356 MockRead(SYNCHRONOUS, OK),
17357 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117358 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417359 session_deps_.socket_factory->AddSocketDataProvider(&data);
17360
17361 TestCompletionCallback callback;
17362
tfarina42834112016-09-22 13:38:2017363 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117364 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417365
17366 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117367 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417368
bnc691fda62016-08-12 00:43:1617369 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217370 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417371
wezca1070932016-05-26 20:30:5217372 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417373 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17374
17375 std::string response_data;
bnc691fda62016-08-12 00:43:1617376 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117377 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417378 EXPECT_EQ("hello world", response_data);
17379}
17380
17381// This tests the more common case than the previous test, where headers and
17382// body are not merged into a single request.
bncd16676a2016-07-20 16:23:0117383TEST_F(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
mmenkecbc2b712014-10-09 20:29:0717384 ChunkedUploadDataStream upload_data_stream(0);
[email protected]02d74a02014-04-23 18:10:5417385
17386 HttpRequestInfo request;
17387 request.method = "POST";
17388 request.url = GURL("http://www.foo.com/");
17389 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017390 request.traffic_annotation =
17391 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417392
danakj1fd259a02016-04-16 03:17:0917393 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617394 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417395 // Send headers successfully, but get an error while sending the body.
17396 MockWrite data_writes[] = {
17397 MockWrite("POST / HTTP/1.1\r\n"
17398 "Host: www.foo.com\r\n"
17399 "Connection: keep-alive\r\n"
17400 "Transfer-Encoding: chunked\r\n\r\n"),
17401 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17402 };
17403
17404 MockRead data_reads[] = {
17405 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17406 MockRead("hello world"),
17407 MockRead(SYNCHRONOUS, OK),
17408 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117409 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417410 session_deps_.socket_factory->AddSocketDataProvider(&data);
17411
17412 TestCompletionCallback callback;
17413
tfarina42834112016-09-22 13:38:2017414 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117415 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417416 // Make sure the headers are sent before adding a chunk. This ensures that
17417 // they can't be merged with the body in a single send. Not currently
17418 // necessary since a chunked body is never merged with headers, but this makes
17419 // the test more future proof.
17420 base::RunLoop().RunUntilIdle();
17421
mmenkecbc2b712014-10-09 20:29:0717422 upload_data_stream.AppendData("last chunk", 10, true);
[email protected]02d74a02014-04-23 18:10:5417423
17424 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117425 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417426
bnc691fda62016-08-12 00:43:1617427 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217428 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417429
wezca1070932016-05-26 20:30:5217430 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417431 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17432
17433 std::string response_data;
bnc691fda62016-08-12 00:43:1617434 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117435 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417436 EXPECT_EQ("hello world", response_data);
17437}
17438
bncd16676a2016-07-20 16:23:0117439TEST_F(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917440 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217441 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917442 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217443 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417444
17445 HttpRequestInfo request;
17446 request.method = "POST";
17447 request.url = GURL("http://www.foo.com/");
17448 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017449 request.traffic_annotation =
17450 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417451
danakj1fd259a02016-04-16 03:17:0917452 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617453 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417454
17455 MockWrite data_writes[] = {
17456 MockWrite("POST / HTTP/1.1\r\n"
17457 "Host: www.foo.com\r\n"
17458 "Connection: keep-alive\r\n"
17459 "Content-Length: 3\r\n\r\n"),
17460 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17461 };
17462
17463 MockRead data_reads[] = {
17464 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17465 MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
17466 MockRead("hello world"),
17467 MockRead(SYNCHRONOUS, OK),
17468 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117469 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417470 session_deps_.socket_factory->AddSocketDataProvider(&data);
17471
17472 TestCompletionCallback callback;
17473
tfarina42834112016-09-22 13:38:2017474 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117475 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417476
17477 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117478 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417479
bnc691fda62016-08-12 00:43:1617480 const HttpResponseInfo* response = trans.GetResponseInfo();
wezca1070932016-05-26 20:30:5217481 ASSERT_TRUE(response);
[email protected]02d74a02014-04-23 18:10:5417482
wezca1070932016-05-26 20:30:5217483 EXPECT_TRUE(response->headers);
[email protected]02d74a02014-04-23 18:10:5417484 EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
17485
17486 std::string response_data;
bnc691fda62016-08-12 00:43:1617487 rv = ReadTransaction(&trans, &response_data);
robpercival214763f2016-07-01 23:27:0117488 EXPECT_THAT(rv, IsOk());
[email protected]02d74a02014-04-23 18:10:5417489 EXPECT_EQ("hello world", response_data);
17490}
17491
bncd16676a2016-07-20 16:23:0117492TEST_F(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917493 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217494 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917495 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217496 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417497
17498 HttpRequestInfo request;
17499 request.method = "POST";
17500 request.url = GURL("http://www.foo.com/");
17501 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017502 request.traffic_annotation =
17503 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417504
danakj1fd259a02016-04-16 03:17:0917505 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617506 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417507 // Send headers successfully, but get an error while sending the body.
17508 MockWrite data_writes[] = {
17509 MockWrite("POST / HTTP/1.1\r\n"
17510 "Host: www.foo.com\r\n"
17511 "Connection: keep-alive\r\n"
17512 "Content-Length: 3\r\n\r\n"),
17513 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17514 };
17515
17516 MockRead data_reads[] = {
17517 MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
17518 MockRead("hello world"),
17519 MockRead(SYNCHRONOUS, OK),
17520 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117521 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417522 session_deps_.socket_factory->AddSocketDataProvider(&data);
17523
17524 TestCompletionCallback callback;
17525
tfarina42834112016-09-22 13:38:2017526 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117527 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417528
17529 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117530 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417531}
17532
bncd16676a2016-07-20 16:23:0117533TEST_F(HttpNetworkTransactionTest,
[email protected]02d74a02014-04-23 18:10:5417534 PostIgnoresNonErrorResponseAfterResetAnd100) {
danakj1fd259a02016-04-16 03:17:0917535 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217536 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917537 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217538 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417539
17540 HttpRequestInfo request;
17541 request.method = "POST";
17542 request.url = GURL("http://www.foo.com/");
17543 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017544 request.traffic_annotation =
17545 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417546
danakj1fd259a02016-04-16 03:17:0917547 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617548 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417549 // Send headers successfully, but get an error while sending the body.
17550 MockWrite data_writes[] = {
17551 MockWrite("POST / HTTP/1.1\r\n"
17552 "Host: www.foo.com\r\n"
17553 "Connection: keep-alive\r\n"
17554 "Content-Length: 3\r\n\r\n"),
17555 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17556 };
17557
17558 MockRead data_reads[] = {
17559 MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
17560 MockRead("HTTP/1.0 302 Redirect\r\n"),
17561 MockRead("Location: http://somewhere-else.com/\r\n"),
17562 MockRead("Content-Length: 0\r\n\r\n"),
17563 MockRead(SYNCHRONOUS, OK),
17564 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117565 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417566 session_deps_.socket_factory->AddSocketDataProvider(&data);
17567
17568 TestCompletionCallback callback;
17569
tfarina42834112016-09-22 13:38:2017570 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117571 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417572
17573 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117574 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417575}
17576
bncd16676a2016-07-20 16:23:0117577TEST_F(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
danakj1fd259a02016-04-16 03:17:0917578 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217579 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917580 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217581 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417582
17583 HttpRequestInfo request;
17584 request.method = "POST";
17585 request.url = GURL("http://www.foo.com/");
17586 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017587 request.traffic_annotation =
17588 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417589
danakj1fd259a02016-04-16 03:17:0917590 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617591 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417592 // Send headers successfully, but get an error while sending the body.
17593 MockWrite data_writes[] = {
17594 MockWrite("POST / HTTP/1.1\r\n"
17595 "Host: www.foo.com\r\n"
17596 "Connection: keep-alive\r\n"
17597 "Content-Length: 3\r\n\r\n"),
17598 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17599 };
17600
17601 MockRead data_reads[] = {
17602 MockRead("HTTP 0.9 rocks!"),
17603 MockRead(SYNCHRONOUS, OK),
17604 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117605 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417606 session_deps_.socket_factory->AddSocketDataProvider(&data);
17607
17608 TestCompletionCallback callback;
17609
tfarina42834112016-09-22 13:38:2017610 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117611 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417612
17613 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117614 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417615}
17616
bncd16676a2016-07-20 16:23:0117617TEST_F(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
danakj1fd259a02016-04-16 03:17:0917618 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217619 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917620 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217621 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]02d74a02014-04-23 18:10:5417622
17623 HttpRequestInfo request;
17624 request.method = "POST";
17625 request.url = GURL("http://www.foo.com/");
17626 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017627 request.traffic_annotation =
17628 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
[email protected]02d74a02014-04-23 18:10:5417629
danakj1fd259a02016-04-16 03:17:0917630 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617631 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
[email protected]02d74a02014-04-23 18:10:5417632 // Send headers successfully, but get an error while sending the body.
17633 MockWrite data_writes[] = {
17634 MockWrite("POST / HTTP/1.1\r\n"
17635 "Host: www.foo.com\r\n"
17636 "Connection: keep-alive\r\n"
17637 "Content-Length: 3\r\n\r\n"),
17638 MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
17639 };
17640
17641 MockRead data_reads[] = {
17642 MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
17643 MockRead(SYNCHRONOUS, OK),
17644 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117645 StaticSocketDataProvider data(data_reads, data_writes);
[email protected]02d74a02014-04-23 18:10:5417646 session_deps_.socket_factory->AddSocketDataProvider(&data);
17647
17648 TestCompletionCallback callback;
17649
tfarina42834112016-09-22 13:38:2017650 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117651 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
[email protected]02d74a02014-04-23 18:10:5417652
17653 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117654 EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET));
[email protected]02d74a02014-04-23 18:10:5417655}
17656
Bence Békydca6bd92018-01-30 13:43:0617657#if BUILDFLAG(ENABLE_WEBSOCKETS)
17658
17659namespace {
17660
17661void AddWebSocketHeaders(HttpRequestHeaders* headers) {
17662 headers->SetHeader("Connection", "Upgrade");
17663 headers->SetHeader("Upgrade", "websocket");
17664 headers->SetHeader("Origin", "http://www.example.org");
17665 headers->SetHeader("Sec-WebSocket-Version", "13");
Bence Békydca6bd92018-01-30 13:43:0617666}
17667
17668} // namespace
17669
17670TEST_F(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
Bence Béky2fcf4fa2018-04-06 20:06:0117671 for (bool secure : {true, false}) {
17672 MockWrite data_writes[] = {
17673 MockWrite("GET / HTTP/1.1\r\n"
17674 "Host: www.example.org\r\n"
17675 "Connection: Upgrade\r\n"
17676 "Upgrade: websocket\r\n"
17677 "Origin: http://www.example.org\r\n"
17678 "Sec-WebSocket-Version: 13\r\n"
17679 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17680 "Sec-WebSocket-Extensions: permessage-deflate; "
17681 "client_max_window_bits\r\n\r\n")};
17682
17683 MockRead data_reads[] = {
17684 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17685 "Upgrade: websocket\r\n"
17686 "Connection: Upgrade\r\n"
17687 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
17688
Ryan Sleevib8d7ea02018-05-07 20:01:0117689 StaticSocketDataProvider data(data_reads, data_writes);
Bence Béky2fcf4fa2018-04-06 20:06:0117690 session_deps_.socket_factory->AddSocketDataProvider(&data);
17691 SSLSocketDataProvider ssl(ASYNC, OK);
17692 if (secure)
17693 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
Bence Békydca6bd92018-01-30 13:43:0617694
17695 HttpRequestInfo request;
17696 request.method = "GET";
Bence Béky2fcf4fa2018-04-06 20:06:0117697 request.url =
17698 GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
17699 AddWebSocketHeaders(&request.extra_headers);
Ramin Halavatib5e433e62018-02-07 07:41:1017700 request.traffic_annotation =
17701 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Bence Békydca6bd92018-01-30 13:43:0617702
Bence Béky2fcf4fa2018-04-06 20:06:0117703 TestWebSocketHandshakeStreamCreateHelper
17704 websocket_handshake_stream_create_helper;
Bence Béky8d1c6052018-02-07 12:48:1517705
Bence Béky2fcf4fa2018-04-06 20:06:0117706 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Bence Békydca6bd92018-01-30 13:43:0617707 HttpNetworkTransaction trans(LOW, session.get());
17708 trans.SetWebSocketHandshakeStreamCreateHelper(
Bence Béky2fcf4fa2018-04-06 20:06:0117709 &websocket_handshake_stream_create_helper);
Bence Békydca6bd92018-01-30 13:43:0617710
17711 TestCompletionCallback callback;
Bence Béky2fcf4fa2018-04-06 20:06:0117712 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17713 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Bence Békydca6bd92018-01-30 13:43:0617714
Bence Béky2fcf4fa2018-04-06 20:06:0117715 const HttpStreamRequest* stream_request = trans.stream_request_.get();
17716 ASSERT_TRUE(stream_request);
17717 EXPECT_EQ(&websocket_handshake_stream_create_helper,
17718 stream_request->websocket_handshake_stream_create_helper());
17719
17720 rv = callback.WaitForResult();
17721 EXPECT_THAT(rv, IsOk());
17722
17723 EXPECT_TRUE(data.AllReadDataConsumed());
17724 EXPECT_TRUE(data.AllWriteDataConsumed());
Bence Békydca6bd92018-01-30 13:43:0617725 }
17726}
17727
Adam Rice425cf122015-01-19 06:18:2417728// Verify that proxy headers are not sent to the destination server when
17729// establishing a tunnel for a secure WebSocket connection.
bncd16676a2016-07-20 16:23:0117730TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWssTunnel) {
Adam Rice425cf122015-01-19 06:18:2417731 HttpRequestInfo request;
17732 request.method = "GET";
bncce36dca22015-04-21 22:11:2317733 request.url = GURL("wss://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017734 request.traffic_annotation =
17735 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417736 AddWebSocketHeaders(&request.extra_headers);
17737
17738 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917739 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917740 ProxyResolutionService::CreateFixedFromPacResult(
17741 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417742
danakj1fd259a02016-04-16 03:17:0917743 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417744
17745 // Since a proxy is configured, try to establish a tunnel.
17746 MockWrite data_writes[] = {
rsleevidb16bb02015-11-12 23:47:1717747 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17748 "Host: www.example.org:443\r\n"
17749 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417750
17751 // After calling trans->RestartWithAuth(), this is the request we should
17752 // be issuing -- the final header line contains the credentials.
rsleevidb16bb02015-11-12 23:47:1717753 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
17754 "Host: www.example.org:443\r\n"
17755 "Proxy-Connection: keep-alive\r\n"
17756 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417757
rsleevidb16bb02015-11-12 23:47:1717758 MockWrite("GET / HTTP/1.1\r\n"
17759 "Host: www.example.org\r\n"
17760 "Connection: Upgrade\r\n"
17761 "Upgrade: websocket\r\n"
17762 "Origin: http://www.example.org\r\n"
17763 "Sec-WebSocket-Version: 13\r\n"
Bence Béky8d1c6052018-02-07 12:48:1517764 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17765 "Sec-WebSocket-Extensions: permessage-deflate; "
17766 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417767
17768 // The proxy responds to the connect with a 407, using a persistent
17769 // connection.
17770 MockRead data_reads[] = {
17771 // No credentials.
Bence Béky8d1c6052018-02-07 12:48:1517772 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"
17773 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
17774 "Content-Length: 0\r\n"
17775 "Proxy-Connection: keep-alive\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417776
17777 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17778
Bence Béky8d1c6052018-02-07 12:48:1517779 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17780 "Upgrade: websocket\r\n"
17781 "Connection: Upgrade\r\n"
17782 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417783
Ryan Sleevib8d7ea02018-05-07 20:01:0117784 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417785 session_deps_.socket_factory->AddSocketDataProvider(&data);
17786 SSLSocketDataProvider ssl(ASYNC, OK);
17787 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
17788
Bence Béky8d1c6052018-02-07 12:48:1517789 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17790
bnc87dcefc2017-05-25 12:47:5817791 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917792 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417793 trans->SetWebSocketHandshakeStreamCreateHelper(
17794 &websocket_stream_create_helper);
17795
17796 {
17797 TestCompletionCallback callback;
17798
tfarina42834112016-09-22 13:38:2017799 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117800 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417801
17802 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117803 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417804 }
17805
17806 const HttpResponseInfo* response = trans->GetResponseInfo();
17807 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217808 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417809 EXPECT_EQ(407, response->headers->response_code());
17810
17811 {
17812 TestCompletionCallback callback;
17813
17814 int rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
17815 callback.callback());
robpercival214763f2016-07-01 23:27:0117816 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417817
17818 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117819 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417820 }
17821
17822 response = trans->GetResponseInfo();
17823 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217824 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417825
17826 EXPECT_EQ(101, response->headers->response_code());
17827
17828 trans.reset();
17829 session->CloseAllConnections();
17830}
17831
17832// Verify that proxy headers are not sent to the destination server when
17833// establishing a tunnel for an insecure WebSocket connection.
17834// This requires the authentication info to be injected into the auth cache
17835// due to crbug.com/395064
17836// TODO(ricea): Change to use a 407 response once issue 395064 is fixed.
bncd16676a2016-07-20 16:23:0117837TEST_F(HttpNetworkTransactionTest, ProxyHeadersNotSentOverWsTunnel) {
Adam Rice425cf122015-01-19 06:18:2417838 HttpRequestInfo request;
17839 request.method = "GET";
bncce36dca22015-04-21 22:11:2317840 request.url = GURL("ws://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1017841 request.traffic_annotation =
17842 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417843 AddWebSocketHeaders(&request.extra_headers);
17844
17845 // Configure against proxy server "myproxy:70".
Lily Houghton8c2f97d2018-01-22 05:06:5917846 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4917847 ProxyResolutionService::CreateFixedFromPacResult(
17848 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
Adam Rice425cf122015-01-19 06:18:2417849
danakj1fd259a02016-04-16 03:17:0917850 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
Adam Rice425cf122015-01-19 06:18:2417851
17852 MockWrite data_writes[] = {
17853 // Try to establish a tunnel for the WebSocket connection, with
17854 // credentials. Because WebSockets have a separate set of socket pools,
17855 // they cannot and will not use the same TCP/IP connection as the
17856 // preflight HTTP request.
Bence Béky8d1c6052018-02-07 12:48:1517857 MockWrite("CONNECT www.example.org:80 HTTP/1.1\r\n"
17858 "Host: www.example.org:80\r\n"
17859 "Proxy-Connection: keep-alive\r\n"
17860 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
Adam Rice425cf122015-01-19 06:18:2417861
Bence Béky8d1c6052018-02-07 12:48:1517862 MockWrite("GET / HTTP/1.1\r\n"
17863 "Host: www.example.org\r\n"
17864 "Connection: Upgrade\r\n"
17865 "Upgrade: websocket\r\n"
17866 "Origin: http://www.example.org\r\n"
17867 "Sec-WebSocket-Version: 13\r\n"
17868 "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n"
17869 "Sec-WebSocket-Extensions: permessage-deflate; "
17870 "client_max_window_bits\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417871
17872 MockRead data_reads[] = {
17873 // HTTP CONNECT with credentials.
17874 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
17875
17876 // WebSocket connection established inside tunnel.
Bence Béky8d1c6052018-02-07 12:48:1517877 MockRead("HTTP/1.1 101 Switching Protocols\r\n"
17878 "Upgrade: websocket\r\n"
17879 "Connection: Upgrade\r\n"
17880 "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")};
Adam Rice425cf122015-01-19 06:18:2417881
Ryan Sleevib8d7ea02018-05-07 20:01:0117882 StaticSocketDataProvider data(data_reads, data_writes);
Adam Rice425cf122015-01-19 06:18:2417883 session_deps_.socket_factory->AddSocketDataProvider(&data);
17884
17885 session->http_auth_cache()->Add(
17886 GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
17887 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
17888
Bence Béky8d1c6052018-02-07 12:48:1517889 TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper;
17890
bnc87dcefc2017-05-25 12:47:5817891 auto trans =
Jeremy Roman0579ed62017-08-29 15:56:1917892 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Adam Rice425cf122015-01-19 06:18:2417893 trans->SetWebSocketHandshakeStreamCreateHelper(
17894 &websocket_stream_create_helper);
17895
17896 TestCompletionCallback callback;
17897
tfarina42834112016-09-22 13:38:2017898 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
robpercival214763f2016-07-01 23:27:0117899 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
Adam Rice425cf122015-01-19 06:18:2417900
17901 rv = callback.WaitForResult();
robpercival214763f2016-07-01 23:27:0117902 EXPECT_THAT(rv, IsOk());
Adam Rice425cf122015-01-19 06:18:2417903
17904 const HttpResponseInfo* response = trans->GetResponseInfo();
17905 ASSERT_TRUE(response);
wezca1070932016-05-26 20:30:5217906 ASSERT_TRUE(response->headers);
Adam Rice425cf122015-01-19 06:18:2417907
17908 EXPECT_EQ(101, response->headers->response_code());
17909
17910 trans.reset();
17911 session->CloseAllConnections();
17912}
17913
Matt Menke1d6093e32019-03-22 17:33:4317914// WebSockets over QUIC is not supported, including over QUIC proxies.
17915TEST_F(HttpNetworkTransactionTest, WebSocketNotSentOverQuicProxy) {
17916 for (bool secure : {true, false}) {
17917 SCOPED_TRACE(secure);
17918 session_deps_.proxy_resolution_service =
17919 ProxyResolutionService::CreateFixedFromPacResult(
17920 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
17921 session_deps_.enable_quic = true;
17922
17923 HttpRequestInfo request;
17924 request.url =
17925 GURL(secure ? "ws://www.example.org/" : "wss://www.example.org/");
17926 AddWebSocketHeaders(&request.extra_headers);
17927 request.traffic_annotation =
17928 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
17929
17930 TestWebSocketHandshakeStreamCreateHelper
17931 websocket_handshake_stream_create_helper;
17932
17933 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
17934 HttpNetworkTransaction trans(LOW, session.get());
17935 trans.SetWebSocketHandshakeStreamCreateHelper(
17936 &websocket_handshake_stream_create_helper);
17937
17938 TestCompletionCallback callback;
17939 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
17940 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
17941
17942 rv = callback.WaitForResult();
17943 EXPECT_THAT(rv, IsError(ERR_NO_SUPPORTED_PROXIES));
17944 }
17945}
17946
Bence Békydca6bd92018-01-30 13:43:0617947#endif // BUILDFLAG(ENABLE_WEBSOCKETS)
17948
bncd16676a2016-07-20 16:23:0117949TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost) {
danakj1fd259a02016-04-16 03:17:0917950 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217951 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917952 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217953 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217954
17955 HttpRequestInfo request;
17956 request.method = "POST";
17957 request.url = GURL("http://www.foo.com/");
17958 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1017959 request.traffic_annotation =
17960 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2217961
danakj1fd259a02016-04-16 03:17:0917962 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1617963 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2217964 MockWrite data_writes[] = {
17965 MockWrite("POST / HTTP/1.1\r\n"
17966 "Host: www.foo.com\r\n"
17967 "Connection: keep-alive\r\n"
17968 "Content-Length: 3\r\n\r\n"),
17969 MockWrite("foo"),
17970 };
17971
17972 MockRead data_reads[] = {
17973 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
17974 MockRead(SYNCHRONOUS, OK),
17975 };
Ryan Sleevib8d7ea02018-05-07 20:01:0117976 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2217977 session_deps_.socket_factory->AddSocketDataProvider(&data);
17978
17979 TestCompletionCallback callback;
17980
17981 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2017982 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0117983 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2217984
17985 std::string response_data;
bnc691fda62016-08-12 00:43:1617986 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2217987
Ryan Sleevib8d7ea02018-05-07 20:01:0117988 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
17989 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2217990}
17991
bncd16676a2016-07-20 16:23:0117992TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) {
danakj1fd259a02016-04-16 03:17:0917993 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
olli.raula6df48b2a2015-11-26 07:40:2217994 element_readers.push_back(
Jeremy Roman0579ed62017-08-29 15:56:1917995 std::make_unique<UploadBytesElementReader>("foo", 3));
olli.raula6df48b2a2015-11-26 07:40:2217996 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
sclittlefb249892015-09-10 21:33:2217997
17998 HttpRequestInfo request;
17999 request.method = "POST";
18000 request.url = GURL("http://www.foo.com/");
18001 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1018002 request.traffic_annotation =
18003 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2218004
danakj1fd259a02016-04-16 03:17:0918005 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1618006 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2218007 MockWrite data_writes[] = {
18008 MockWrite("POST / HTTP/1.1\r\n"
18009 "Host: www.foo.com\r\n"
18010 "Connection: keep-alive\r\n"
18011 "Content-Length: 3\r\n\r\n"),
18012 MockWrite("foo"),
18013 };
18014
18015 MockRead data_reads[] = {
18016 MockRead("HTTP/1.1 100 Continue\r\n\r\n"),
18017 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
18018 MockRead(SYNCHRONOUS, OK),
18019 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118020 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2218021 session_deps_.socket_factory->AddSocketDataProvider(&data);
18022
18023 TestCompletionCallback callback;
18024
18025 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2018026 trans.Start(&request, callback.callback(), NetLogWithSource()));
robpercival214763f2016-07-01 23:27:0118027 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2218028
18029 std::string response_data;
bnc691fda62016-08-12 00:43:1618030 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2218031
Ryan Sleevib8d7ea02018-05-07 20:01:0118032 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
18033 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2218034}
18035
bncd16676a2016-07-20 16:23:0118036TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) {
sclittlefb249892015-09-10 21:33:2218037 ChunkedUploadDataStream upload_data_stream(0);
18038
18039 HttpRequestInfo request;
18040 request.method = "POST";
18041 request.url = GURL("http://www.foo.com/");
18042 request.upload_data_stream = &upload_data_stream;
Ramin Halavatib5e433e62018-02-07 07:41:1018043 request.traffic_annotation =
18044 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
sclittlefb249892015-09-10 21:33:2218045
danakj1fd259a02016-04-16 03:17:0918046 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
bnc691fda62016-08-12 00:43:1618047 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
sclittlefb249892015-09-10 21:33:2218048 // Send headers successfully, but get an error while sending the body.
18049 MockWrite data_writes[] = {
18050 MockWrite("POST / HTTP/1.1\r\n"
18051 "Host: www.foo.com\r\n"
18052 "Connection: keep-alive\r\n"
18053 "Transfer-Encoding: chunked\r\n\r\n"),
18054 MockWrite("1\r\nf\r\n"), MockWrite("2\r\noo\r\n"), MockWrite("0\r\n\r\n"),
18055 };
18056
18057 MockRead data_reads[] = {
18058 MockRead("HTTP/1.1 200 OK\r\n\r\n"), MockRead("hello world"),
18059 MockRead(SYNCHRONOUS, OK),
18060 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118061 StaticSocketDataProvider data(data_reads, data_writes);
sclittlefb249892015-09-10 21:33:2218062 session_deps_.socket_factory->AddSocketDataProvider(&data);
18063
18064 TestCompletionCallback callback;
18065
18066 EXPECT_EQ(ERR_IO_PENDING,
tfarina42834112016-09-22 13:38:2018067 trans.Start(&request, callback.callback(), NetLogWithSource()));
sclittlefb249892015-09-10 21:33:2218068
18069 base::RunLoop().RunUntilIdle();
18070 upload_data_stream.AppendData("f", 1, false);
18071
18072 base::RunLoop().RunUntilIdle();
18073 upload_data_stream.AppendData("oo", 2, true);
18074
robpercival214763f2016-07-01 23:27:0118075 EXPECT_THAT(callback.WaitForResult(), IsOk());
sclittlefb249892015-09-10 21:33:2218076
18077 std::string response_data;
bnc691fda62016-08-12 00:43:1618078 EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk());
sclittlefb249892015-09-10 21:33:2218079
Ryan Sleevib8d7ea02018-05-07 20:01:0118080 EXPECT_EQ(CountWriteBytes(data_writes), trans.GetTotalSentBytes());
18081 EXPECT_EQ(CountReadBytes(data_reads), trans.GetTotalReceivedBytes());
sclittlefb249892015-09-10 21:33:2218082}
18083
eustasc7d27da2017-04-06 10:33:2018084void CheckContentEncodingMatching(SpdySessionDependencies* session_deps,
18085 const std::string& accept_encoding,
18086 const std::string& content_encoding,
sky50576f32017-05-01 19:28:0318087 const std::string& location,
eustasc7d27da2017-04-06 10:33:2018088 bool should_match) {
18089 HttpRequestInfo request;
18090 request.method = "GET";
18091 request.url = GURL("http://www.foo.com/");
18092 request.extra_headers.SetHeader(HttpRequestHeaders::kAcceptEncoding,
18093 accept_encoding);
Ramin Halavatib5e433e62018-02-07 07:41:1018094 request.traffic_annotation =
18095 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
eustasc7d27da2017-04-06 10:33:2018096
18097 std::unique_ptr<HttpNetworkSession> session(CreateSession(session_deps));
18098 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18099 // Send headers successfully, but get an error while sending the body.
18100 MockWrite data_writes[] = {
18101 MockWrite("GET / HTTP/1.1\r\n"
18102 "Host: www.foo.com\r\n"
18103 "Connection: keep-alive\r\n"
18104 "Accept-Encoding: "),
18105 MockWrite(accept_encoding.data()), MockWrite("\r\n\r\n"),
18106 };
18107
sky50576f32017-05-01 19:28:0318108 std::string response_code = "200 OK";
18109 std::string extra;
18110 if (!location.empty()) {
18111 response_code = "301 Redirect\r\nLocation: ";
18112 response_code.append(location);
18113 }
18114
eustasc7d27da2017-04-06 10:33:2018115 MockRead data_reads[] = {
sky50576f32017-05-01 19:28:0318116 MockRead("HTTP/1.0 "),
18117 MockRead(response_code.data()),
18118 MockRead("\r\nContent-Encoding: "),
18119 MockRead(content_encoding.data()),
18120 MockRead("\r\n\r\n"),
eustasc7d27da2017-04-06 10:33:2018121 MockRead(SYNCHRONOUS, OK),
18122 };
Ryan Sleevib8d7ea02018-05-07 20:01:0118123 StaticSocketDataProvider data(data_reads, data_writes);
eustasc7d27da2017-04-06 10:33:2018124 session_deps->socket_factory->AddSocketDataProvider(&data);
18125
18126 TestCompletionCallback callback;
18127
18128 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18129 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18130
18131 rv = callback.WaitForResult();
18132 if (should_match) {
18133 EXPECT_THAT(rv, IsOk());
18134 } else {
18135 EXPECT_THAT(rv, IsError(ERR_CONTENT_DECODING_FAILED));
18136 }
18137}
18138
18139TEST_F(HttpNetworkTransactionTest, MatchContentEncoding1) {
sky50576f32017-05-01 19:28:0318140 CheckContentEncodingMatching(&session_deps_, "gzip,sdch", "br", "", false);
eustasc7d27da2017-04-06 10:33:2018141}
18142
18143TEST_F(HttpNetworkTransactionTest, MatchContentEncoding2) {
sky50576f32017-05-01 19:28:0318144 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "", "",
18145 true);
eustasc7d27da2017-04-06 10:33:2018146}
18147
18148TEST_F(HttpNetworkTransactionTest, MatchContentEncoding3) {
18149 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
sky50576f32017-05-01 19:28:0318150 "", false);
18151}
18152
18153TEST_F(HttpNetworkTransactionTest, MatchContentEncoding4) {
18154 CheckContentEncodingMatching(&session_deps_, "identity;q=1, *;q=0", "gzip",
18155 "www.foo.com/other", true);
eustasc7d27da2017-04-06 10:33:2018156}
18157
xunjieli96f2a402017-06-05 17:24:2718158TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsSync) {
18159 ProxyConfig proxy_config;
18160 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18161 proxy_config.set_pac_mandatory(true);
18162 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918163 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918164 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18165 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Bence Béky8f9d7d3952017-10-09 19:58:0418166 std::make_unique<FailingProxyResolverFactory>(), nullptr));
xunjieli96f2a402017-06-05 17:24:2718167
18168 HttpRequestInfo request;
18169 request.method = "GET";
18170 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1018171 request.traffic_annotation =
18172 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718173
18174 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18175 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18176
18177 TestCompletionCallback callback;
18178
18179 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18180 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18181 EXPECT_THAT(callback.WaitForResult(),
18182 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18183}
18184
18185TEST_F(HttpNetworkTransactionTest, ProxyResolutionFailsAsync) {
18186 ProxyConfig proxy_config;
18187 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
18188 proxy_config.set_pac_mandatory(true);
18189 MockAsyncProxyResolverFactory* proxy_resolver_factory =
18190 new MockAsyncProxyResolverFactory(false);
18191 MockAsyncProxyResolver resolver;
Lily Houghton8c2f97d2018-01-22 05:06:5918192 session_deps_.proxy_resolution_service.reset(new ProxyResolutionService(
Ramin Halavatica8d5252018-03-12 05:33:4918193 std::make_unique<ProxyConfigServiceFixed>(ProxyConfigWithAnnotation(
18194 proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS)),
Lily Houghton8c2f97d2018-01-22 05:06:5918195 base::WrapUnique(proxy_resolver_factory), nullptr));
xunjieli96f2a402017-06-05 17:24:2718196 HttpRequestInfo request;
18197 request.method = "GET";
18198 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1018199 request.traffic_annotation =
18200 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718201
18202 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18203 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18204
18205 TestCompletionCallback callback;
18206 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18207 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18208
18209 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
18210 ERR_FAILED, &resolver);
18211 EXPECT_THAT(callback.WaitForResult(),
18212 IsError(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED));
18213}
18214
18215TEST_F(HttpNetworkTransactionTest, NoSupportedProxies) {
Lily Houghton8c2f97d2018-01-22 05:06:5918216 session_deps_.proxy_resolution_service =
Ramin Halavatica8d5252018-03-12 05:33:4918217 ProxyResolutionService::CreateFixedFromPacResult(
18218 "QUIC myproxy.org:443", TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718219 session_deps_.enable_quic = false;
18220 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18221
18222 HttpRequestInfo request;
18223 request.method = "GET";
18224 request.url = GURL("http://www.example.org/");
Ramin Halavatib5e433e62018-02-07 07:41:1018225 request.traffic_annotation =
18226 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
xunjieli96f2a402017-06-05 17:24:2718227
18228 TestCompletionCallback callback;
18229 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18230 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
18231 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18232
18233 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NO_SUPPORTED_PROXIES));
18234}
18235
Douglas Creager3cb042052018-11-06 23:08:5218236//-----------------------------------------------------------------------------
Douglas Creager134b52e2018-11-09 18:00:1418237// Reporting tests
18238
18239#if BUILDFLAG(ENABLE_REPORTING)
18240class HttpNetworkTransactionReportingTest : public HttpNetworkTransactionTest {
18241 protected:
18242 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618243 HttpNetworkTransactionTest::SetUp();
Douglas Creager134b52e2018-11-09 18:00:1418244 auto test_reporting_context = std::make_unique<TestReportingContext>(
18245 &clock_, &tick_clock_, ReportingPolicy());
18246 test_reporting_context_ = test_reporting_context.get();
18247 session_deps_.reporting_service =
18248 ReportingService::CreateForTesting(std::move(test_reporting_context));
18249 }
18250
18251 TestReportingContext* reporting_context() const {
18252 return test_reporting_context_;
18253 }
18254
18255 void clear_reporting_service() {
18256 session_deps_.reporting_service.reset();
18257 test_reporting_context_ = nullptr;
18258 }
18259
18260 // Makes an HTTPS request that should install a valid Reporting policy.
Lily Chenfec60d92019-01-24 01:16:4218261 void RequestPolicy(CertStatus cert_status = 0) {
18262 HttpRequestInfo request;
18263 request.method = "GET";
18264 request.url = GURL(url_);
18265 request.traffic_annotation =
18266 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18267
Lily Chend3930e72019-03-01 19:31:1118268 MockWrite data_writes[] = {
18269 MockWrite("GET / HTTP/1.1\r\n"
18270 "Host: www.example.org\r\n"
18271 "Connection: keep-alive\r\n\r\n"),
18272 };
Douglas Creager134b52e2018-11-09 18:00:1418273 MockRead data_reads[] = {
18274 MockRead("HTTP/1.0 200 OK\r\n"),
18275 MockRead("Report-To: {\"group\": \"nel\", \"max_age\": 86400, "
18276 "\"endpoints\": [{\"url\": "
18277 "\"https://www.example.org/upload/\"}]}\r\n"),
18278 MockRead("\r\n"),
18279 MockRead("hello world"),
18280 MockRead(SYNCHRONOUS, OK),
18281 };
Douglas Creager134b52e2018-11-09 18:00:1418282
Lily Chenfec60d92019-01-24 01:16:4218283 StaticSocketDataProvider reads(data_reads, data_writes);
18284 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager134b52e2018-11-09 18:00:1418285
18286 SSLSocketDataProvider ssl(ASYNC, OK);
18287 if (request.url.SchemeIsCryptographic()) {
18288 ssl.ssl_info.cert =
18289 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18290 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218291 ssl.ssl_info.cert_status = cert_status;
Douglas Creager134b52e2018-11-09 18:00:1418292 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18293 }
18294
Douglas Creager134b52e2018-11-09 18:00:1418295 TestCompletionCallback callback;
18296 auto session = CreateSession(&session_deps_);
18297 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18298 int rv = trans.Start(&request, callback.callback(), NetLogWithSource());
Lily Chenfec60d92019-01-24 01:16:4218299 EXPECT_THAT(callback.GetResult(rv), IsOk());
Douglas Creager134b52e2018-11-09 18:00:1418300 }
18301
18302 protected:
18303 std::string url_ = "https://www.example.org/";
Douglas Creager134b52e2018-11-09 18:00:1418304
18305 private:
18306 TestReportingContext* test_reporting_context_;
18307};
18308
18309TEST_F(HttpNetworkTransactionReportingTest,
18310 DontProcessReportToHeaderNoService) {
18311 base::HistogramTester histograms;
18312 clear_reporting_service();
18313 RequestPolicy();
18314 histograms.ExpectBucketCount(
18315 ReportingHeaderParser::kHeaderOutcomeHistogram,
18316 ReportingHeaderParser::HeaderOutcome::DISCARDED_NO_REPORTING_SERVICE, 1);
18317}
18318
18319TEST_F(HttpNetworkTransactionReportingTest, DontProcessReportToHeaderHttp) {
18320 base::HistogramTester histograms;
18321 url_ = "http://www.example.org/";
18322 RequestPolicy();
18323 histograms.ExpectBucketCount(
18324 ReportingHeaderParser::kHeaderOutcomeHistogram,
18325 ReportingHeaderParser::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18326}
18327
18328TEST_F(HttpNetworkTransactionReportingTest, ProcessReportToHeaderHttps) {
18329 RequestPolicy();
Lily Chenefb6fcf2019-04-19 04:17:5418330 ASSERT_EQ(1u, reporting_context()->cache()->GetEndpointCount());
18331 const ReportingClient endpoint =
18332 reporting_context()->cache()->GetEndpointForTesting(
18333 url::Origin::Create(GURL("https://www.example.org/")), "nel",
18334 GURL("https://www.example.org/upload/"));
18335 EXPECT_TRUE(endpoint);
Douglas Creager134b52e2018-11-09 18:00:1418336}
18337
18338TEST_F(HttpNetworkTransactionReportingTest,
18339 DontProcessReportToHeaderInvalidHttps) {
18340 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218341 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18342 RequestPolicy(cert_status);
Douglas Creager134b52e2018-11-09 18:00:1418343 histograms.ExpectBucketCount(
18344 ReportingHeaderParser::kHeaderOutcomeHistogram,
18345 ReportingHeaderParser::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR, 1);
18346}
18347#endif // BUILDFLAG(ENABLE_REPORTING)
18348
18349//-----------------------------------------------------------------------------
Douglas Creager3cb042052018-11-06 23:08:5218350// Network Error Logging tests
18351
18352#if BUILDFLAG(ENABLE_REPORTING)
Lily Chenfec60d92019-01-24 01:16:4218353namespace {
18354
18355const char kUserAgent[] = "Mozilla/1.0";
18356const char kReferrer[] = "https://www.referrer.org/";
18357
18358} // namespace
18359
Douglas Creager3cb042052018-11-06 23:08:5218360class HttpNetworkTransactionNetworkErrorLoggingTest
18361 : public HttpNetworkTransactionTest {
18362 protected:
18363 void SetUp() override {
Douglas Creageref5eecdc2018-11-09 20:50:3618364 HttpNetworkTransactionTest::SetUp();
Douglas Creager3cb042052018-11-06 23:08:5218365 auto network_error_logging_service =
18366 std::make_unique<TestNetworkErrorLoggingService>();
18367 test_network_error_logging_service_ = network_error_logging_service.get();
18368 session_deps_.network_error_logging_service =
18369 std::move(network_error_logging_service);
Lily Chenfec60d92019-01-24 01:16:4218370
18371 extra_headers_.SetHeader("User-Agent", kUserAgent);
18372 extra_headers_.SetHeader("Referer", kReferrer);
18373
18374 request_.method = "GET";
18375 request_.url = GURL(url_);
18376 request_.extra_headers = extra_headers_;
18377 request_.reporting_upload_depth = reporting_upload_depth_;
18378 request_.traffic_annotation =
18379 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Douglas Creager3cb042052018-11-06 23:08:5218380 }
18381
18382 TestNetworkErrorLoggingService* network_error_logging_service() const {
18383 return test_network_error_logging_service_;
18384 }
18385
18386 void clear_network_error_logging_service() {
18387 session_deps_.network_error_logging_service.reset();
18388 test_network_error_logging_service_ = nullptr;
18389 }
18390
18391 // Makes an HTTPS request that should install a valid NEL policy.
Lily Chenfec60d92019-01-24 01:16:4218392 void RequestPolicy(CertStatus cert_status = 0) {
Douglas Creageref5eecdc2018-11-09 20:50:3618393 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318394 MockWrite data_writes[] = {
18395 MockWrite("GET / HTTP/1.1\r\n"
18396 "Host: www.example.org\r\n"
18397 "Connection: keep-alive\r\n"),
18398 MockWrite(ASYNC, extra_header_string.data(),
18399 extra_header_string.size()),
18400 };
Lily Chend3930e72019-03-01 19:31:1118401 MockRead data_reads[] = {
18402 MockRead("HTTP/1.0 200 OK\r\n"),
18403 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
18404 MockRead("\r\n"),
18405 MockRead("hello world"),
18406 MockRead(SYNCHRONOUS, OK),
18407 };
Douglas Creager3cb042052018-11-06 23:08:5218408
Lily Chenfec60d92019-01-24 01:16:4218409 StaticSocketDataProvider reads(data_reads, data_writes);
18410 session_deps_.socket_factory->AddSocketDataProvider(&reads);
Douglas Creager3cb042052018-11-06 23:08:5218411
18412 SSLSocketDataProvider ssl(ASYNC, OK);
Lily Chenfec60d92019-01-24 01:16:4218413 if (request_.url.SchemeIsCryptographic()) {
Douglas Creager3cb042052018-11-06 23:08:5218414 ssl.ssl_info.cert =
18415 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18416 ASSERT_TRUE(ssl.ssl_info.cert);
Lily Chenfec60d92019-01-24 01:16:4218417 ssl.ssl_info.cert_status = cert_status;
Douglas Creager3cb042052018-11-06 23:08:5218418 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18419 }
18420
Douglas Creager3cb042052018-11-06 23:08:5218421 TestCompletionCallback callback;
18422 auto session = CreateSession(&session_deps_);
18423 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
Lily Chenfec60d92019-01-24 01:16:4218424 int rv = trans.Start(&request_, callback.callback(), NetLogWithSource());
18425 EXPECT_THAT(callback.GetResult(rv), IsOk());
18426
18427 std::string response_data;
18428 ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk());
18429 EXPECT_EQ("hello world", response_data);
18430 }
18431
18432 void CheckReport(size_t index,
18433 int status_code,
18434 int error_type,
18435 IPAddress server_ip = IPAddress::IPv4Localhost()) {
18436 ASSERT_LT(index, network_error_logging_service()->errors().size());
18437
18438 const NetworkErrorLoggingService::RequestDetails& error =
18439 network_error_logging_service()->errors()[index];
18440 EXPECT_EQ(url_, error.uri);
18441 EXPECT_EQ(kReferrer, error.referrer);
18442 EXPECT_EQ(kUserAgent, error.user_agent);
18443 EXPECT_EQ(server_ip, error.server_ip);
18444 EXPECT_EQ("http/1.1", error.protocol);
18445 EXPECT_EQ("GET", error.method);
18446 EXPECT_EQ(status_code, error.status_code);
18447 EXPECT_EQ(error_type, error.type);
18448 EXPECT_EQ(0, error.reporting_upload_depth);
Douglas Creager3cb042052018-11-06 23:08:5218449 }
18450
18451 protected:
18452 std::string url_ = "https://www.example.org/";
18453 CertStatus cert_status_ = 0;
Lily Chenfec60d92019-01-24 01:16:4218454 HttpRequestInfo request_;
Douglas Creageref5eecdc2018-11-09 20:50:3618455 HttpRequestHeaders extra_headers_;
18456 int reporting_upload_depth_ = 0;
Douglas Creager3cb042052018-11-06 23:08:5218457
18458 private:
18459 TestNetworkErrorLoggingService* test_network_error_logging_service_;
18460};
18461
18462TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18463 DontProcessNelHeaderNoService) {
18464 base::HistogramTester histograms;
18465 clear_network_error_logging_service();
18466 RequestPolicy();
18467 histograms.ExpectBucketCount(
18468 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18469 NetworkErrorLoggingService::HeaderOutcome::
18470 DISCARDED_NO_NETWORK_ERROR_LOGGING_SERVICE,
18471 1);
18472}
18473
18474TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18475 DontProcessNelHeaderHttp) {
18476 base::HistogramTester histograms;
18477 url_ = "http://www.example.org/";
Lily Chenfec60d92019-01-24 01:16:4218478 request_.url = GURL(url_);
Douglas Creager3cb042052018-11-06 23:08:5218479 RequestPolicy();
18480 histograms.ExpectBucketCount(
18481 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18482 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_INVALID_SSL_INFO, 1);
18483}
18484
Lily Chen90ae93cc2019-02-14 01:15:3918485// Don't set NEL policies received on a proxied connection.
18486TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18487 DontProcessNelHeaderProxy) {
18488 session_deps_.proxy_resolution_service =
18489 ProxyResolutionService::CreateFixedFromPacResult(
18490 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
18491 BoundTestNetLog log;
18492 session_deps_.net_log = log.bound().net_log();
18493 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18494
18495 HttpRequestInfo request;
18496 request.method = "GET";
18497 request.url = GURL("https://www.example.org/");
18498 request.traffic_annotation =
18499 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
18500
18501 // Since we have proxy, should try to establish tunnel.
18502 MockWrite data_writes1[] = {
18503 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
18504 "Host: www.example.org:443\r\n"
18505 "Proxy-Connection: keep-alive\r\n\r\n"),
18506
18507 MockWrite("GET / HTTP/1.1\r\n"
18508 "Host: www.example.org\r\n"
18509 "Connection: keep-alive\r\n\r\n"),
18510 };
18511
18512 MockRead data_reads1[] = {
18513 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
18514
18515 MockRead("HTTP/1.1 200 OK\r\n"),
18516 MockRead("NEL: {\"report_to\": \"nel\", \"max_age\": 86400}\r\n"),
18517 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18518 MockRead("Content-Length: 100\r\n\r\n"),
18519 MockRead(SYNCHRONOUS, OK),
18520 };
18521
18522 StaticSocketDataProvider data1(data_reads1, data_writes1);
18523 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18524 SSLSocketDataProvider ssl(ASYNC, OK);
18525 ssl.ssl_info.cert =
18526 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem");
18527 ASSERT_TRUE(ssl.ssl_info.cert);
18528 ssl.ssl_info.cert_status = 0;
18529 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18530
18531 TestCompletionCallback callback1;
18532 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
18533
18534 int rv = trans.Start(&request, callback1.callback(), log.bound());
18535 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
18536
18537 rv = callback1.WaitForResult();
18538 EXPECT_THAT(rv, IsOk());
18539
18540 const HttpResponseInfo* response = trans.GetResponseInfo();
18541 ASSERT_TRUE(response);
18542 EXPECT_EQ(200, response->headers->response_code());
18543 EXPECT_TRUE(response->was_fetched_via_proxy);
18544
18545 // No NEL header was set.
18546 EXPECT_EQ(0u, network_error_logging_service()->headers().size());
18547}
18548
Douglas Creager3cb042052018-11-06 23:08:5218549TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ProcessNelHeaderHttps) {
18550 RequestPolicy();
18551 ASSERT_EQ(1u, network_error_logging_service()->headers().size());
18552 const auto& header = network_error_logging_service()->headers()[0];
18553 EXPECT_EQ(url::Origin::Create(GURL("https://www.example.org/")),
18554 header.origin);
18555 EXPECT_EQ(IPAddress::IPv4Localhost(), header.received_ip_address);
18556 EXPECT_EQ("{\"report_to\": \"nel\", \"max_age\": 86400}", header.value);
18557}
18558
18559TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18560 DontProcessNelHeaderInvalidHttps) {
18561 base::HistogramTester histograms;
Lily Chenfec60d92019-01-24 01:16:4218562 CertStatus cert_status = CERT_STATUS_COMMON_NAME_INVALID;
18563 RequestPolicy(cert_status);
Douglas Creager3cb042052018-11-06 23:08:5218564 histograms.ExpectBucketCount(
18565 NetworkErrorLoggingService::kHeaderOutcomeHistogram,
18566 NetworkErrorLoggingService::HeaderOutcome::DISCARDED_CERT_STATUS_ERROR,
18567 1);
18568}
Douglas Creageref5eecdc2018-11-09 20:50:3618569
Lily Chenfec60d92019-01-24 01:16:4218570TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, CreateReportSuccess) {
Douglas Creageref5eecdc2018-11-09 20:50:3618571 RequestPolicy();
18572 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4218573 CheckReport(0 /* index */, 200 /* status_code */, OK);
18574}
18575
18576TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18577 CreateReportErrorAfterStart) {
18578 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18579 auto trans =
18580 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18581
18582 MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED);
18583 StaticSocketDataProvider data;
18584 data.set_connect_data(mock_connect);
18585 session_deps_.socket_factory->AddSocketDataProvider(&data);
18586
18587 TestCompletionCallback callback;
18588
18589 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18590 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18591
18592 trans.reset();
18593
18594 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18595 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18596 IPAddress() /* server_ip */);
18597}
18598
18599// Same as above except the error is ASYNC
18600TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18601 CreateReportErrorAfterStartAsync) {
18602 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18603 auto trans =
18604 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18605
18606 MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED);
18607 StaticSocketDataProvider data;
18608 data.set_connect_data(mock_connect);
18609 session_deps_.socket_factory->AddSocketDataProvider(&data);
18610
18611 TestCompletionCallback callback;
18612
18613 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18614 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NAME_NOT_RESOLVED));
18615
18616 trans.reset();
18617
18618 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18619 CheckReport(0 /* index */, 0 /* status_code */, ERR_NAME_NOT_RESOLVED,
18620 IPAddress() /* server_ip */);
18621}
18622
18623TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18624 CreateReportReadBodyError) {
18625 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318626 MockWrite data_writes[] = {
18627 MockWrite("GET / HTTP/1.1\r\n"
18628 "Host: www.example.org\r\n"
18629 "Connection: keep-alive\r\n"),
18630 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18631 };
Lily Chend3930e72019-03-01 19:31:1118632 MockRead data_reads[] = {
18633 MockRead("HTTP/1.0 200 OK\r\n"),
18634 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18635 MockRead("hello world"),
18636 MockRead(SYNCHRONOUS, OK),
18637 };
Lily Chenfec60d92019-01-24 01:16:4218638
18639 StaticSocketDataProvider reads(data_reads, data_writes);
18640 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18641
18642 SSLSocketDataProvider ssl(ASYNC, OK);
18643 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18644
18645 // Log start time
18646 base::TimeTicks start_time = base::TimeTicks::Now();
18647
18648 TestCompletionCallback callback;
18649 auto session = CreateSession(&session_deps_);
18650 auto trans =
18651 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18652 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18653 EXPECT_THAT(callback.GetResult(rv), IsOk());
18654
18655 const HttpResponseInfo* response = trans->GetResponseInfo();
18656 ASSERT_TRUE(response);
18657
18658 EXPECT_TRUE(response->headers);
18659 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18660
18661 std::string response_data;
18662 rv = ReadTransaction(trans.get(), &response_data);
18663 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18664
18665 trans.reset();
18666
18667 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18668
18669 CheckReport(0 /* index */, 200 /* status_code */,
18670 ERR_CONTENT_LENGTH_MISMATCH);
18671 const NetworkErrorLoggingService::RequestDetails& error =
18672 network_error_logging_service()->errors()[0];
18673 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18674}
18675
18676// Same as above except the final read is ASYNC.
18677TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18678 CreateReportReadBodyErrorAsync) {
18679 std::string extra_header_string = extra_headers_.ToString();
Lily Chen29c04032019-02-25 21:50:5318680 MockWrite data_writes[] = {
18681 MockWrite("GET / HTTP/1.1\r\n"
18682 "Host: www.example.org\r\n"
18683 "Connection: keep-alive\r\n"),
18684 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18685 };
Lily Chend3930e72019-03-01 19:31:1118686 MockRead data_reads[] = {
18687 MockRead("HTTP/1.0 200 OK\r\n"),
18688 MockRead("Content-Length: 100\r\n\r\n"), // wrong content length
18689 MockRead("hello world"),
18690 MockRead(ASYNC, OK),
18691 };
Lily Chenfec60d92019-01-24 01:16:4218692
18693 StaticSocketDataProvider reads(data_reads, data_writes);
18694 session_deps_.socket_factory->AddSocketDataProvider(&reads);
18695
18696 SSLSocketDataProvider ssl(ASYNC, OK);
18697 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
18698
18699 // Log start time
18700 base::TimeTicks start_time = base::TimeTicks::Now();
18701
18702 TestCompletionCallback callback;
18703 auto session = CreateSession(&session_deps_);
18704 auto trans =
18705 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18706 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
18707 EXPECT_THAT(callback.GetResult(rv), IsOk());
18708
18709 const HttpResponseInfo* response = trans->GetResponseInfo();
18710 ASSERT_TRUE(response);
18711
18712 EXPECT_TRUE(response->headers);
18713 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
18714
18715 std::string response_data;
18716 rv = ReadTransaction(trans.get(), &response_data);
18717 EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH));
18718
18719 trans.reset();
18720
18721 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18722
18723 CheckReport(0 /* index */, 200 /* status_code */,
18724 ERR_CONTENT_LENGTH_MISMATCH);
18725 const NetworkErrorLoggingService::RequestDetails& error =
18726 network_error_logging_service()->errors()[0];
18727 EXPECT_LE(error.elapsed_time, base::TimeTicks::Now() - start_time);
18728}
18729
18730TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18731 CreateReportRestartWithAuth) {
18732 std::string extra_header_string = extra_headers_.ToString();
18733 static const base::TimeDelta kSleepDuration =
18734 base::TimeDelta::FromMilliseconds(10);
18735
18736 MockWrite data_writes1[] = {
18737 MockWrite("GET / HTTP/1.1\r\n"
18738 "Host: www.example.org\r\n"
18739 "Connection: keep-alive\r\n"),
18740 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18741 };
18742
18743 MockRead data_reads1[] = {
18744 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18745 // Give a couple authenticate options (only the middle one is actually
18746 // supported).
18747 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18748 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18749 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18750 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18751 // Large content-length -- won't matter, as connection will be reset.
18752 MockRead("Content-Length: 10000\r\n\r\n"),
18753 MockRead(SYNCHRONOUS, ERR_FAILED),
18754 };
18755
18756 // After calling trans->RestartWithAuth(), this is the request we should
18757 // be issuing -- the final header line contains the credentials.
18758 MockWrite data_writes2[] = {
18759 MockWrite("GET / HTTP/1.1\r\n"
18760 "Host: www.example.org\r\n"
18761 "Connection: keep-alive\r\n"
18762 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18763 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18764 };
18765
18766 // Lastly, the server responds with the actual content.
18767 MockRead data_reads2[] = {
18768 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18769 MockRead("hello world"),
18770 MockRead(SYNCHRONOUS, OK),
18771 };
18772
18773 StaticSocketDataProvider data1(data_reads1, data_writes1);
18774 StaticSocketDataProvider data2(data_reads2, data_writes2);
18775 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18776 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18777
18778 SSLSocketDataProvider ssl1(ASYNC, OK);
18779 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18780 SSLSocketDataProvider ssl2(ASYNC, OK);
18781 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18782
18783 base::TimeTicks start_time = base::TimeTicks::Now();
18784 base::TimeTicks restart_time;
18785
18786 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18787 auto trans =
18788 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18789
18790 TestCompletionCallback callback1;
18791
18792 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18793 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18794
18795 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18796
18797 TestCompletionCallback callback2;
18798
18799 // Wait 10 ms then restart with auth
18800 FastForwardBy(kSleepDuration);
18801 restart_time = base::TimeTicks::Now();
18802 rv =
18803 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18804 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18805
18806 std::string response_data;
18807 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18808 EXPECT_EQ("hello world", response_data);
18809
18810 trans.reset();
18811
18812 // One 401 report for the auth challenge, then a 200 report for the successful
18813 // retry. Note that we don't report the error draining the body, as the first
18814 // request already generated a report for the auth challenge.
18815 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18816
18817 // Check error report contents
18818 CheckReport(0 /* index */, 401 /* status_code */, OK);
18819 CheckReport(1 /* index */, 200 /* status_code */, OK);
18820
18821 const NetworkErrorLoggingService::RequestDetails& error1 =
18822 network_error_logging_service()->errors()[0];
18823 const NetworkErrorLoggingService::RequestDetails& error2 =
18824 network_error_logging_service()->errors()[1];
18825
18826 // Sanity-check elapsed time values
18827 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18828 // Check that the start time is refreshed when restarting with auth.
18829 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
18830}
18831
18832// Same as above, except draining the body before restarting fails
18833// asynchronously.
18834TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18835 CreateReportRestartWithAuthAsync) {
18836 std::string extra_header_string = extra_headers_.ToString();
18837 static const base::TimeDelta kSleepDuration =
18838 base::TimeDelta::FromMilliseconds(10);
18839
18840 MockWrite data_writes1[] = {
18841 MockWrite("GET / HTTP/1.1\r\n"
18842 "Host: www.example.org\r\n"
18843 "Connection: keep-alive\r\n"),
18844 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18845 };
18846
18847 MockRead data_reads1[] = {
18848 MockRead("HTTP/1.0 401 Unauthorized\r\n"),
18849 // Give a couple authenticate options (only the middle one is actually
18850 // supported).
18851 MockRead("WWW-Authenticate: Basic invalid\r\n"), // Malformed.
18852 MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
18853 MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
18854 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
18855 // Large content-length -- won't matter, as connection will be reset.
18856 MockRead("Content-Length: 10000\r\n\r\n"),
18857 MockRead(ASYNC, ERR_FAILED),
18858 };
18859
18860 // After calling trans->RestartWithAuth(), this is the request we should
18861 // be issuing -- the final header line contains the credentials.
18862 MockWrite data_writes2[] = {
18863 MockWrite("GET / HTTP/1.1\r\n"
18864 "Host: www.example.org\r\n"
18865 "Connection: keep-alive\r\n"
18866 "Authorization: Basic Zm9vOmJhcg==\r\n"),
18867 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18868 };
18869
18870 // Lastly, the server responds with the actual content.
18871 MockRead data_reads2[] = {
18872 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
18873 MockRead("hello world"),
18874 MockRead(SYNCHRONOUS, OK),
18875 };
18876
18877 StaticSocketDataProvider data1(data_reads1, data_writes1);
18878 StaticSocketDataProvider data2(data_reads2, data_writes2);
18879 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18880 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18881
18882 SSLSocketDataProvider ssl1(ASYNC, OK);
18883 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18884 SSLSocketDataProvider ssl2(ASYNC, OK);
18885 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18886
18887 base::TimeTicks start_time = base::TimeTicks::Now();
18888 base::TimeTicks restart_time;
18889
18890 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18891 auto trans =
18892 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18893
18894 TestCompletionCallback callback1;
18895
18896 int rv = trans->Start(&request_, callback1.callback(), NetLogWithSource());
18897 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18898
18899 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18900
18901 TestCompletionCallback callback2;
18902
18903 // Wait 10 ms then restart with auth
18904 FastForwardBy(kSleepDuration);
18905 restart_time = base::TimeTicks::Now();
18906 rv =
18907 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
18908 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18909
18910 std::string response_data;
18911 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
18912 EXPECT_EQ("hello world", response_data);
18913
18914 trans.reset();
18915
18916 // One 401 report for the auth challenge, then a 200 report for the successful
18917 // retry. Note that we don't report the error draining the body, as the first
18918 // request already generated a report for the auth challenge.
18919 ASSERT_EQ(2u, network_error_logging_service()->errors().size());
18920
18921 // Check error report contents
18922 CheckReport(0 /* index */, 401 /* status_code */, OK);
18923 CheckReport(1 /* index */, 200 /* status_code */, OK);
18924
18925 const NetworkErrorLoggingService::RequestDetails& error1 =
18926 network_error_logging_service()->errors()[0];
18927 const NetworkErrorLoggingService::RequestDetails& error2 =
18928 network_error_logging_service()->errors()[1];
18929
18930 // Sanity-check elapsed time values
18931 EXPECT_EQ(error1.elapsed_time, restart_time - start_time - kSleepDuration);
18932 // Check that the start time is refreshed when restarting with auth.
18933 EXPECT_EQ(error2.elapsed_time, base::TimeTicks::Now() - restart_time);
18934}
18935
18936TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
18937 CreateReportRetryKeepAliveConnectionReset) {
18938 std::string extra_header_string = extra_headers_.ToString();
18939 MockWrite data_writes1[] = {
18940 MockWrite("GET / HTTP/1.1\r\n"
18941 "Host: www.example.org\r\n"
18942 "Connection: keep-alive\r\n"),
18943 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18944 MockWrite("GET / HTTP/1.1\r\n"
18945 "Host: www.example.org\r\n"
18946 "Connection: keep-alive\r\n"),
18947 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
18948 };
18949
18950 MockRead data_reads1[] = {
18951 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18952 MockRead("hello"),
18953 // Connection is reset
18954 MockRead(ASYNC, ERR_CONNECTION_RESET),
18955 };
18956
18957 // Successful retry
18958 MockRead data_reads2[] = {
18959 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
18960 MockRead("world"),
18961 MockRead(ASYNC, OK),
18962 };
18963
18964 StaticSocketDataProvider data1(data_reads1, data_writes1);
18965 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
18966 session_deps_.socket_factory->AddSocketDataProvider(&data1);
18967 session_deps_.socket_factory->AddSocketDataProvider(&data2);
18968
18969 SSLSocketDataProvider ssl1(ASYNC, OK);
18970 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
18971 SSLSocketDataProvider ssl2(ASYNC, OK);
18972 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
18973
18974 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
18975 auto trans1 =
18976 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18977
18978 TestCompletionCallback callback1;
18979
18980 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
18981 EXPECT_THAT(callback1.GetResult(rv), IsOk());
18982
18983 std::string response_data;
18984 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
18985 EXPECT_EQ("hello", response_data);
18986
18987 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
18988
18989 auto trans2 =
18990 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
18991
18992 TestCompletionCallback callback2;
18993
18994 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
18995 EXPECT_THAT(callback2.GetResult(rv), IsOk());
18996
18997 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
18998 EXPECT_EQ("world", response_data);
18999
19000 trans1.reset();
19001 trans2.reset();
19002
19003 // One OK report from first request, then a ERR_CONNECTION_RESET report from
19004 // the second request, then an OK report from the successful retry.
19005 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19006
19007 // Check error report contents
19008 CheckReport(0 /* index */, 200 /* status_code */, OK);
19009 CheckReport(1 /* index */, 0 /* status_code */, ERR_CONNECTION_RESET);
19010 CheckReport(2 /* index */, 200 /* status_code */, OK);
19011}
19012
19013TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19014 CreateReportRetryKeepAlive408) {
19015 std::string extra_header_string = extra_headers_.ToString();
19016 MockWrite data_writes1[] = {
19017 MockWrite("GET / HTTP/1.1\r\n"
19018 "Host: www.example.org\r\n"
19019 "Connection: keep-alive\r\n"),
19020 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19021 MockWrite("GET / HTTP/1.1\r\n"
19022 "Host: www.example.org\r\n"
19023 "Connection: keep-alive\r\n"),
19024 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19025 };
19026
19027 MockRead data_reads1[] = {
19028 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
19029 MockRead("hello"),
19030 // 408 Request Timeout
19031 MockRead(SYNCHRONOUS,
19032 "HTTP/1.1 408 Request Timeout\r\n"
19033 "Connection: Keep-Alive\r\n"
19034 "Content-Length: 6\r\n\r\n"
19035 "Pickle"),
19036 };
19037
19038 // Successful retry
19039 MockRead data_reads2[] = {
19040 MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
19041 MockRead("world"),
19042 MockRead(ASYNC, OK),
19043 };
19044
19045 StaticSocketDataProvider data1(data_reads1, data_writes1);
19046 StaticSocketDataProvider data2(data_reads2, base::span<MockWrite>());
19047 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19048 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19049
19050 SSLSocketDataProvider ssl1(ASYNC, OK);
19051 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
19052 SSLSocketDataProvider ssl2(ASYNC, OK);
19053 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
19054
19055 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19056 auto trans1 =
19057 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19058
19059 TestCompletionCallback callback1;
19060
19061 int rv = trans1->Start(&request_, callback1.callback(), NetLogWithSource());
19062 EXPECT_THAT(callback1.GetResult(rv), IsOk());
19063
19064 std::string response_data;
19065 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19066 EXPECT_EQ("hello", response_data);
19067
19068 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19069
19070 auto trans2 =
19071 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19072
19073 TestCompletionCallback callback2;
19074
19075 rv = trans2->Start(&request_, callback2.callback(), NetLogWithSource());
19076 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19077
19078 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19079 EXPECT_EQ("world", response_data);
19080
19081 trans1.reset();
19082 trans2.reset();
19083
19084 // One 200 report from first request, then a 408 report from
19085 // the second request, then a 200 report from the successful retry.
19086 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19087
19088 // Check error report contents
19089 CheckReport(0 /* index */, 200 /* status_code */, OK);
19090 CheckReport(1 /* index */, 408 /* status_code */, OK);
19091 CheckReport(2 /* index */, 200 /* status_code */, OK);
19092}
19093
19094TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19095 CreateReportRetry421WithoutConnectionPooling) {
19096 // Two hosts resolve to the same IP address.
19097 const std::string ip_addr = "1.2.3.4";
19098 IPAddress ip;
19099 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr));
19100 IPEndPoint peer_addr = IPEndPoint(ip, 443);
19101
19102 session_deps_.host_resolver = std::make_unique<MockCachingHostResolver>();
19103 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr);
19104 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr);
19105
19106 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19107
19108 // Two requests on the first connection.
19109 spdy::SpdySerializedFrame req1(
19110 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
19111 spdy_util_.UpdateWithStreamDestruction(1);
19112 spdy::SpdySerializedFrame req2(
19113 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST));
19114 spdy::SpdySerializedFrame rst(
19115 spdy_util_.ConstructSpdyRstStream(3, spdy::ERROR_CODE_CANCEL));
19116 MockWrite writes1[] = {
19117 CreateMockWrite(req1, 0),
19118 CreateMockWrite(req2, 3),
19119 CreateMockWrite(rst, 6),
19120 };
19121
19122 // The first one succeeds, the second gets error 421 Misdirected Request.
19123 spdy::SpdySerializedFrame resp1(
19124 spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
19125 spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true));
19126 spdy::SpdyHeaderBlock response_headers;
19127 response_headers[spdy::kHttp2StatusHeader] = "421";
19128 spdy::SpdySerializedFrame resp2(
19129 spdy_util_.ConstructSpdyReply(3, std::move(response_headers)));
19130 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2),
19131 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)};
19132
19133 MockConnect connect1(ASYNC, OK, peer_addr);
19134 SequencedSocketData data1(connect1, reads1, writes1);
19135 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19136
19137 AddSSLSocketData();
19138
19139 // Retry the second request on a second connection.
19140 SpdyTestUtil spdy_util2;
19141 spdy::SpdySerializedFrame req3(
19142 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST));
19143 MockWrite writes2[] = {
19144 CreateMockWrite(req3, 0),
19145 };
19146
19147 spdy::SpdySerializedFrame resp3(
19148 spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1));
19149 spdy::SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true));
19150 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2),
19151 MockRead(ASYNC, 0, 3)};
19152
19153 MockConnect connect2(ASYNC, OK, peer_addr);
19154 SequencedSocketData data2(connect2, reads2, writes2);
19155 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19156
19157 AddSSLSocketData();
19158
19159 // Preload mail.example.org into HostCache.
Eric Orthf4db66a2019-02-19 21:35:3319160 int rv = session_deps_.host_resolver->LoadIntoCache(
19161 HostPortPair("mail.example.com", 443), base::nullopt);
19162 EXPECT_THAT(rv, IsOk());
Lily Chenfec60d92019-01-24 01:16:4219163
19164 HttpRequestInfo request1;
19165 request1.method = "GET";
19166 request1.url = GURL("https://www.example.org/");
19167 request1.load_flags = 0;
19168 request1.traffic_annotation =
19169 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19170 auto trans1 =
19171 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19172
Eric Orthf4db66a2019-02-19 21:35:3319173 TestCompletionCallback callback;
Lily Chenfec60d92019-01-24 01:16:4219174 rv = trans1->Start(&request1, callback.callback(), NetLogWithSource());
19175 EXPECT_THAT(callback.GetResult(rv), IsOk());
19176
19177 const HttpResponseInfo* response = trans1->GetResponseInfo();
19178 ASSERT_TRUE(response);
19179 ASSERT_TRUE(response->headers);
19180 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19181 EXPECT_TRUE(response->was_fetched_via_spdy);
19182 EXPECT_TRUE(response->was_alpn_negotiated);
19183 std::string response_data;
19184 ASSERT_THAT(ReadTransaction(trans1.get(), &response_data), IsOk());
19185 EXPECT_EQ("hello!", response_data);
19186
19187 trans1.reset();
19188
19189 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19190
19191 HttpRequestInfo request2;
19192 request2.method = "GET";
19193 request2.url = GURL("https://mail.example.org/");
19194 request2.load_flags = 0;
19195 request2.traffic_annotation =
19196 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19197 auto trans2 =
19198 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19199
19200 BoundTestNetLog log;
19201 rv = trans2->Start(&request2, callback.callback(), log.bound());
19202 EXPECT_THAT(callback.GetResult(rv), IsOk());
19203
19204 response = trans2->GetResponseInfo();
19205 ASSERT_TRUE(response);
19206 ASSERT_TRUE(response->headers);
19207 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
19208 EXPECT_TRUE(response->was_fetched_via_spdy);
19209 EXPECT_TRUE(response->was_alpn_negotiated);
19210 ASSERT_THAT(ReadTransaction(trans2.get(), &response_data), IsOk());
19211 EXPECT_EQ("hello!", response_data);
19212
19213 trans2.reset();
19214
19215 // One 200 report from the first request, then a 421 report from the
19216 // second request, then a 200 report from the successful retry.
19217 ASSERT_EQ(3u, network_error_logging_service()->errors().size());
19218
19219 // Check error report contents
19220 const NetworkErrorLoggingService::RequestDetails& error1 =
19221 network_error_logging_service()->errors()[0];
19222 EXPECT_EQ(GURL("https://www.example.org/"), error1.uri);
19223 EXPECT_TRUE(error1.referrer.is_empty());
19224 EXPECT_EQ("", error1.user_agent);
19225 EXPECT_EQ(ip, error1.server_ip);
19226 EXPECT_EQ("h2", error1.protocol);
19227 EXPECT_EQ("GET", error1.method);
19228 EXPECT_EQ(200, error1.status_code);
19229 EXPECT_EQ(OK, error1.type);
19230 EXPECT_EQ(0, error1.reporting_upload_depth);
19231
19232 const NetworkErrorLoggingService::RequestDetails& error2 =
19233 network_error_logging_service()->errors()[1];
19234 EXPECT_EQ(GURL("https://mail.example.org/"), error2.uri);
19235 EXPECT_TRUE(error2.referrer.is_empty());
19236 EXPECT_EQ("", error2.user_agent);
19237 EXPECT_EQ(ip, error2.server_ip);
19238 EXPECT_EQ("h2", error2.protocol);
19239 EXPECT_EQ("GET", error2.method);
19240 EXPECT_EQ(421, error2.status_code);
19241 EXPECT_EQ(OK, error2.type);
19242 EXPECT_EQ(0, error2.reporting_upload_depth);
19243
19244 const NetworkErrorLoggingService::RequestDetails& error3 =
19245 network_error_logging_service()->errors()[2];
19246 EXPECT_EQ(GURL("https://mail.example.org/"), error3.uri);
19247 EXPECT_TRUE(error3.referrer.is_empty());
19248 EXPECT_EQ("", error3.user_agent);
19249 EXPECT_EQ(ip, error3.server_ip);
19250 EXPECT_EQ("h2", error3.protocol);
19251 EXPECT_EQ("GET", error3.method);
19252 EXPECT_EQ(200, error3.status_code);
19253 EXPECT_EQ(OK, error3.type);
19254 EXPECT_EQ(0, error3.reporting_upload_depth);
Douglas Creageref5eecdc2018-11-09 20:50:3619255}
19256
Lily Chend3930e72019-03-01 19:31:1119257TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19258 CreateReportCancelAfterStart) {
19259 StaticSocketDataProvider data;
19260 data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING));
19261 session_deps_.socket_factory->AddSocketDataProvider(&data);
19262
19263 TestCompletionCallback callback;
19264 auto session = CreateSession(&session_deps_);
19265 auto trans =
19266 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19267 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19268 EXPECT_EQ(rv, ERR_IO_PENDING);
19269
19270 // Cancel after start.
19271 trans.reset();
19272
19273 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19274 CheckReport(0 /* index */, 0 /* status_code */, ERR_ABORTED,
19275 IPAddress() /* server_ip */);
19276}
19277
19278TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19279 CreateReportCancelBeforeReadingBody) {
19280 std::string extra_header_string = extra_headers_.ToString();
19281 MockWrite data_writes[] = {
19282 MockWrite("GET / HTTP/1.1\r\n"
19283 "Host: www.example.org\r\n"
19284 "Connection: keep-alive\r\n"),
19285 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19286 };
19287 MockRead data_reads[] = {
19288 MockRead("HTTP/1.0 200 OK\r\n"),
19289 MockRead("Content-Length: 100\r\n\r\n"), // Body is never read.
19290 };
19291
19292 StaticSocketDataProvider data(data_reads, data_writes);
19293 session_deps_.socket_factory->AddSocketDataProvider(&data);
19294
19295 SSLSocketDataProvider ssl(ASYNC, OK);
19296 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19297
19298 TestCompletionCallback callback;
19299 auto session = CreateSession(&session_deps_);
19300 auto trans =
19301 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19302 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19303 EXPECT_THAT(callback.GetResult(rv), IsOk());
19304
19305 const HttpResponseInfo* response = trans->GetResponseInfo();
19306 ASSERT_TRUE(response);
19307
19308 EXPECT_TRUE(response->headers);
19309 EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
19310
19311 // Cancel before reading the body.
19312 trans.reset();
19313
19314 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
19315 CheckReport(0 /* index */, 200 /* status_code */, ERR_ABORTED);
19316}
19317
Lily Chen00196ab62018-12-04 19:52:2919318TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportHttp) {
19319 base::HistogramTester histograms;
19320 RequestPolicy();
19321 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19322 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19323
19324 // Make HTTP request
19325 std::string extra_header_string = extra_headers_.ToString();
19326 MockRead data_reads[] = {
19327 MockRead("HTTP/1.0 200 OK\r\n\r\n"),
19328 MockRead("hello world"),
19329 MockRead(SYNCHRONOUS, OK),
19330 };
19331 MockWrite data_writes[] = {
19332 MockWrite("GET / HTTP/1.1\r\n"
19333 "Host: www.example.org\r\n"
19334 "Connection: keep-alive\r\n"),
19335 MockWrite(ASYNC, extra_header_string.data(), extra_header_string.size()),
19336 };
19337
Lily Chend3930e72019-03-01 19:31:1119338 StaticSocketDataProvider data(data_reads, data_writes);
19339 session_deps_.socket_factory->AddSocketDataProvider(&data);
Lily Chen00196ab62018-12-04 19:52:2919340
Lily Chenfec60d92019-01-24 01:16:4219341 // Insecure url
19342 url_ = "http://www.example.org/";
19343 request_.url = GURL(url_);
19344
Lily Chen00196ab62018-12-04 19:52:2919345 TestCompletionCallback callback;
19346 auto session = CreateSession(&session_deps_);
Lily Chenfec60d92019-01-24 01:16:4219347 auto trans =
19348 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19349 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19350 EXPECT_THAT(callback.GetResult(rv), IsOk());
19351
19352 std::string response_data;
19353 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19354 EXPECT_EQ("hello world", response_data);
Lily Chen00196ab62018-12-04 19:52:2919355
19356 // Insecure request does not generate a report
19357 histograms.ExpectBucketCount(
19358 NetworkErrorLoggingService::kRequestOutcomeHistogram,
Tsuyoshi Horo0b042232019-03-06 01:11:0519359 NetworkErrorLoggingService::RequestOutcome::kDiscardedInsecureOrigin, 1);
Lily Chen00196ab62018-12-04 19:52:2919360
19361 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19362}
19363
19364TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19365 DontCreateReportHttpError) {
19366 base::HistogramTester histograms;
19367 RequestPolicy();
19368 EXPECT_EQ(1u, network_error_logging_service()->headers().size());
19369 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19370
19371 // Make HTTP request that fails
19372 MockRead data_reads[] = {
19373 MockRead("hello world"),
19374 MockRead(SYNCHRONOUS, OK),
19375 };
19376
19377 StaticSocketDataProvider data(data_reads, base::span<MockWrite>());
19378 session_deps_.socket_factory->AddSocketDataProvider(&data);
19379
Lily Chenfec60d92019-01-24 01:16:4219380 url_ = "http://www.originwithoutpolicy.com:2000/";
19381 request_.url = GURL(url_);
19382
Lily Chen00196ab62018-12-04 19:52:2919383 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19384
Lily Chen00196ab62018-12-04 19:52:2919385 auto trans =
19386 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
Lily Chen00196ab62018-12-04 19:52:2919387 TestCompletionCallback callback;
Lily Chenfec60d92019-01-24 01:16:4219388 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
Lily Chen00196ab62018-12-04 19:52:2919389 EXPECT_THAT(callback.GetResult(rv), IsError(ERR_INVALID_HTTP_RESPONSE));
19390
19391 // Insecure request does not generate a report, regardless of existence of a
19392 // policy for the origin.
19393 histograms.ExpectBucketCount(
19394 NetworkErrorLoggingService::kRequestOutcomeHistogram,
Tsuyoshi Horo0b042232019-03-06 01:11:0519395 NetworkErrorLoggingService::RequestOutcome::kDiscardedInsecureOrigin, 1);
Lily Chen00196ab62018-12-04 19:52:2919396
19397 EXPECT_EQ(1u, network_error_logging_service()->errors().size());
19398}
19399
Lily Chen90ae93cc2019-02-14 01:15:3919400// Don't report on proxy auth challenges, don't report if connecting through a
19401// proxy.
19402TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, DontCreateReportProxy) {
19403 HttpRequestInfo request;
19404 request.method = "GET";
19405 request.url = GURL("https://www.example.org/");
19406 request.traffic_annotation =
19407 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19408
19409 // Configure against proxy server "myproxy:70".
19410 session_deps_.proxy_resolution_service =
19411 ProxyResolutionService::CreateFixedFromPacResult(
19412 "PROXY myproxy:70", TRAFFIC_ANNOTATION_FOR_TESTS);
19413 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19414
19415 // Since we have proxy, should try to establish tunnel.
19416 MockWrite data_writes1[] = {
19417 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19418 "Host: www.example.org:443\r\n"
19419 "Proxy-Connection: keep-alive\r\n\r\n"),
19420 };
19421
19422 // The proxy responds to the connect with a 407, using a non-persistent
19423 // connection.
19424 MockRead data_reads1[] = {
19425 // No credentials.
19426 MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
19427 MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
19428 MockRead("Proxy-Connection: close\r\n\r\n"),
19429 };
19430
19431 MockWrite data_writes2[] = {
19432 // After calling trans->RestartWithAuth(), this is the request we should
19433 // be issuing -- the final header line contains the credentials.
19434 MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n"
19435 "Host: www.example.org:443\r\n"
19436 "Proxy-Connection: keep-alive\r\n"
19437 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
19438
19439 MockWrite("GET / HTTP/1.1\r\n"
19440 "Host: www.example.org\r\n"
19441 "Connection: keep-alive\r\n\r\n"),
19442 };
19443
19444 MockRead data_reads2[] = {
19445 MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
19446
19447 MockRead("HTTP/1.1 200 OK\r\n"),
19448 MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
19449 MockRead("Content-Length: 5\r\n\r\n"),
19450 MockRead(SYNCHRONOUS, "hello"),
19451 };
19452
19453 StaticSocketDataProvider data1(data_reads1, data_writes1);
19454 session_deps_.socket_factory->AddSocketDataProvider(&data1);
19455 StaticSocketDataProvider data2(data_reads2, data_writes2);
19456 session_deps_.socket_factory->AddSocketDataProvider(&data2);
19457 SSLSocketDataProvider ssl(ASYNC, OK);
19458 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19459
19460 TestCompletionCallback callback1;
19461
19462 auto trans =
19463 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19464
19465 int rv = trans->Start(&request, callback1.callback(), NetLogWithSource());
19466 EXPECT_THAT(callback1.GetResult(rv), IsOk());
19467
19468 const HttpResponseInfo* response = trans->GetResponseInfo();
19469 EXPECT_EQ(407, response->headers->response_code());
19470
19471 std::string response_data;
19472 rv = ReadTransaction(trans.get(), &response_data);
19473 EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED));
19474
19475 // No NEL report is generated for the 407.
19476 EXPECT_EQ(0u, network_error_logging_service()->errors().size());
19477
19478 TestCompletionCallback callback2;
19479
19480 rv =
19481 trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback());
19482 EXPECT_THAT(callback2.GetResult(rv), IsOk());
19483
19484 response = trans->GetResponseInfo();
19485 EXPECT_EQ(200, response->headers->response_code());
19486
19487 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19488 EXPECT_EQ("hello", response_data);
19489
19490 trans.reset();
19491
19492 // No NEL report is generated because we are behind a proxy.
19493 EXPECT_EQ(0u, network_error_logging_service()->errors().size());
19494}
19495
Douglas Creageref5eecdc2018-11-09 20:50:3619496TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest,
19497 ReportContainsUploadDepth) {
19498 reporting_upload_depth_ = 7;
Lily Chenfec60d92019-01-24 01:16:4219499 request_.reporting_upload_depth = reporting_upload_depth_;
Douglas Creageref5eecdc2018-11-09 20:50:3619500 RequestPolicy();
19501 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219502 const NetworkErrorLoggingService::RequestDetails& error =
19503 network_error_logging_service()->errors()[0];
Douglas Creageref5eecdc2018-11-09 20:50:3619504 EXPECT_EQ(7, error.reporting_upload_depth);
19505}
19506
Lily Chenfec60d92019-01-24 01:16:4219507TEST_F(HttpNetworkTransactionNetworkErrorLoggingTest, ReportElapsedTime) {
19508 std::string extra_header_string = extra_headers_.ToString();
19509 static const base::TimeDelta kSleepDuration =
19510 base::TimeDelta::FromMilliseconds(10);
19511
19512 std::vector<MockWrite> data_writes = {
19513 MockWrite(ASYNC, 0,
19514 "GET / HTTP/1.1\r\n"
19515 "Host: www.example.org\r\n"
19516 "Connection: keep-alive\r\n"),
19517 MockWrite(ASYNC, 1, extra_header_string.data()),
19518 };
19519
19520 std::vector<MockRead> data_reads = {
19521 // Write one byte of the status line, followed by a pause.
19522 MockRead(ASYNC, 2, "H"),
19523 MockRead(ASYNC, ERR_IO_PENDING, 3),
19524 MockRead(ASYNC, 4, "TTP/1.1 200 OK\r\n\r\n"),
19525 MockRead(ASYNC, 5, "hello world"),
19526 MockRead(SYNCHRONOUS, OK, 6),
19527 };
19528
19529 SequencedSocketData data(data_reads, data_writes);
19530 session_deps_.socket_factory->AddSocketDataProvider(&data);
19531
19532 SSLSocketDataProvider ssl(ASYNC, OK);
19533 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19534
19535 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19536
19537 auto trans =
19538 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19539
19540 TestCompletionCallback callback;
19541
19542 int rv = trans->Start(&request_, callback.callback(), NetLogWithSource());
19543 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19544
19545 data.RunUntilPaused();
19546 ASSERT_TRUE(data.IsPaused());
19547 FastForwardBy(kSleepDuration);
19548 data.Resume();
19549
19550 EXPECT_THAT(callback.GetResult(rv), IsOk());
19551
19552 std::string response_data;
19553 ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk());
19554 EXPECT_EQ("hello world", response_data);
19555
19556 trans.reset();
19557
Douglas Creageref5eecdc2018-11-09 20:50:3619558 ASSERT_EQ(1u, network_error_logging_service()->errors().size());
Lily Chenfec60d92019-01-24 01:16:4219559
19560 CheckReport(0 /* index */, 200 /* status_code */, OK);
19561
19562 const NetworkErrorLoggingService::RequestDetails& error =
19563 network_error_logging_service()->errors()[0];
19564
19565 // Sanity-check elapsed time in error report
19566 EXPECT_EQ(kSleepDuration, error.elapsed_time);
Douglas Creageref5eecdc2018-11-09 20:50:3619567}
Lily Chenfec60d92019-01-24 01:16:4219568
Douglas Creager3cb042052018-11-06 23:08:5219569#endif // BUILDFLAG(ENABLE_REPORTING)
19570
Batalov Vladislava4e97a502019-04-11 15:35:2319571TEST_F(HttpNetworkTransactionTest, AlwaysFailRequestToCache) {
19572 HttpRequestInfo request;
19573 request.method = "GET";
19574 request.url = GURL("http://example.org/");
19575
19576 request.load_flags = LOAD_ONLY_FROM_CACHE;
19577
19578 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19579 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
19580 TestCompletionCallback callback1;
19581 int rv = trans.Start(&request, callback1.callback(), NetLogWithSource());
19582
19583 EXPECT_THAT(rv, IsError(ERR_CACHE_MISS));
19584}
19585
Steven Valdez1c1859172019-04-10 15:33:2819586TEST_F(HttpNetworkTransactionTest, ZeroRTTDoesntConfirm) {
19587 HttpRequestInfo request;
19588 request.method = "GET";
19589 request.url = GURL("https://www.example.org/");
19590 request.traffic_annotation =
19591 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19592
19593 MockWrite data_writes[] = {
19594 MockWrite("GET / HTTP/1.1\r\n"
19595 "Host: www.example.org\r\n"
19596 "Connection: keep-alive\r\n\r\n"),
19597 };
19598
19599 // The proxy responds to the connect with a 407, using a persistent
19600 // connection.
19601 MockRead data_reads[] = {
19602 MockRead("HTTP/1.1 200 OK\r\n"),
19603 MockRead("Content-Length: 1\r\n\r\n"),
19604 MockRead(SYNCHRONOUS, "1"),
19605 };
19606
19607 StaticSocketDataProvider data(data_reads, data_writes);
19608 session_deps_.socket_factory->AddSocketDataProvider(&data);
19609 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19610 ssl.confirm = MockConfirm(SYNCHRONOUS, OK);
19611 session_deps_.enable_early_data = true;
19612 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19613
19614 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19615
19616 TestCompletionCallback callback;
19617 auto trans =
19618 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19619
19620 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19621 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19622
19623 rv = callback.WaitForResult();
19624 EXPECT_THAT(rv, IsOk());
19625
19626 const HttpResponseInfo* response = trans->GetResponseInfo();
19627 ASSERT_TRUE(response);
19628 ASSERT_TRUE(response->headers);
19629 EXPECT_EQ(200, response->headers->response_code());
19630 EXPECT_EQ(1, response->headers->GetContentLength());
19631
19632 // Check that ConfirmHandshake wasn't called.
19633 ASSERT_FALSE(ssl.ConfirmDataConsumed());
19634 ASSERT_TRUE(ssl.WriteBeforeConfirm());
19635
19636 trans.reset();
19637
19638 session->CloseAllConnections();
19639}
19640
19641TEST_F(HttpNetworkTransactionTest, ZeroRTTSyncConfirmSyncWrite) {
19642 HttpRequestInfo request;
19643 request.method = "POST";
19644 request.url = GURL("https://www.example.org/");
19645 request.traffic_annotation =
19646 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19647
19648 MockWrite data_writes[] = {
19649 MockWrite(SYNCHRONOUS,
19650 "POST / HTTP/1.1\r\n"
19651 "Host: www.example.org\r\n"
19652 "Connection: keep-alive\r\n"
19653 "Content-Length: 0\r\n\r\n"),
19654 };
19655
19656 // The proxy responds to the connect with a 407, using a persistent
19657 // connection.
19658 MockRead data_reads[] = {
19659 MockRead("HTTP/1.1 200 OK\r\n"),
19660 MockRead("Content-Length: 1\r\n\r\n"),
19661 MockRead(SYNCHRONOUS, "1"),
19662 };
19663
19664 StaticSocketDataProvider data(data_reads, data_writes);
19665 session_deps_.socket_factory->AddSocketDataProvider(&data);
19666 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19667 ssl.confirm = MockConfirm(SYNCHRONOUS, OK);
19668 session_deps_.enable_early_data = true;
19669 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19670
19671 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19672
19673 TestCompletionCallback callback;
19674 auto trans =
19675 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19676
19677 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19678 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19679
19680 rv = callback.WaitForResult();
19681 EXPECT_THAT(rv, IsOk());
19682
19683 const HttpResponseInfo* response = trans->GetResponseInfo();
19684 ASSERT_TRUE(response);
19685 ASSERT_TRUE(response->headers);
19686 EXPECT_EQ(200, response->headers->response_code());
19687 EXPECT_EQ(1, response->headers->GetContentLength());
19688
19689 // Check that the Write didn't get called before ConfirmHandshake completed.
19690 ASSERT_FALSE(ssl.WriteBeforeConfirm());
19691
19692 trans.reset();
19693
19694 session->CloseAllConnections();
19695}
19696
19697TEST_F(HttpNetworkTransactionTest, ZeroRTTSyncConfirmAsyncWrite) {
19698 HttpRequestInfo request;
19699 request.method = "POST";
19700 request.url = GURL("https://www.example.org/");
19701 request.traffic_annotation =
19702 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19703
19704 MockWrite data_writes[] = {
19705 MockWrite(ASYNC,
19706 "POST / HTTP/1.1\r\n"
19707 "Host: www.example.org\r\n"
19708 "Connection: keep-alive\r\n"
19709 "Content-Length: 0\r\n\r\n"),
19710 };
19711
19712 // The proxy responds to the connect with a 407, using a persistent
19713 // connection.
19714 MockRead data_reads[] = {
19715 MockRead("HTTP/1.1 200 OK\r\n"),
19716 MockRead("Content-Length: 1\r\n\r\n"),
19717 MockRead(SYNCHRONOUS, "1"),
19718 };
19719
19720 StaticSocketDataProvider data(data_reads, data_writes);
19721 session_deps_.socket_factory->AddSocketDataProvider(&data);
19722 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19723 ssl.confirm = MockConfirm(SYNCHRONOUS, OK);
19724 session_deps_.enable_early_data = true;
19725 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19726
19727 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19728
19729 TestCompletionCallback callback;
19730 auto trans =
19731 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19732
19733 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19734 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19735
19736 rv = callback.WaitForResult();
19737 EXPECT_THAT(rv, IsOk());
19738
19739 const HttpResponseInfo* response = trans->GetResponseInfo();
19740 ASSERT_TRUE(response);
19741 ASSERT_TRUE(response->headers);
19742 EXPECT_EQ(200, response->headers->response_code());
19743 EXPECT_EQ(1, response->headers->GetContentLength());
19744
19745 // Check that the Write didn't get called before ConfirmHandshake completed.
19746 ASSERT_FALSE(ssl.WriteBeforeConfirm());
19747
19748 trans.reset();
19749
19750 session->CloseAllConnections();
19751}
19752
19753TEST_F(HttpNetworkTransactionTest, ZeroRTTAsyncConfirmSyncWrite) {
19754 HttpRequestInfo request;
19755 request.method = "POST";
19756 request.url = GURL("https://www.example.org/");
19757 request.traffic_annotation =
19758 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19759
19760 MockWrite data_writes[] = {
19761 MockWrite(SYNCHRONOUS,
19762 "POST / HTTP/1.1\r\n"
19763 "Host: www.example.org\r\n"
19764 "Connection: keep-alive\r\n"
19765 "Content-Length: 0\r\n\r\n"),
19766 };
19767
19768 // The proxy responds to the connect with a 407, using a persistent
19769 // connection.
19770 MockRead data_reads[] = {
19771 MockRead("HTTP/1.1 200 OK\r\n"),
19772 MockRead("Content-Length: 1\r\n\r\n"),
19773 MockRead(SYNCHRONOUS, "1"),
19774 };
19775
19776 StaticSocketDataProvider data(data_reads, data_writes);
19777 session_deps_.socket_factory->AddSocketDataProvider(&data);
19778 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19779 ssl.confirm = MockConfirm(ASYNC, OK);
19780 session_deps_.enable_early_data = true;
19781 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19782
19783 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19784
19785 TestCompletionCallback callback;
19786 auto trans =
19787 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19788
19789 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19790 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19791
19792 rv = callback.WaitForResult();
19793 EXPECT_THAT(rv, IsOk());
19794
19795 const HttpResponseInfo* response = trans->GetResponseInfo();
19796 ASSERT_TRUE(response);
19797 ASSERT_TRUE(response->headers);
19798 EXPECT_EQ(200, response->headers->response_code());
19799 EXPECT_EQ(1, response->headers->GetContentLength());
19800
19801 // Check that the Write didn't get called before ConfirmHandshake completed.
19802 ASSERT_FALSE(ssl.WriteBeforeConfirm());
19803
19804 trans.reset();
19805
19806 session->CloseAllConnections();
19807}
19808
19809TEST_F(HttpNetworkTransactionTest, ZeroRTTAsyncConfirmAsyncWrite) {
19810 HttpRequestInfo request;
19811 request.method = "POST";
19812 request.url = GURL("https://www.example.org/");
19813 request.traffic_annotation =
19814 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19815
19816 MockWrite data_writes[] = {
19817 MockWrite(ASYNC,
19818 "POST / HTTP/1.1\r\n"
19819 "Host: www.example.org\r\n"
19820 "Connection: keep-alive\r\n"
19821 "Content-Length: 0\r\n\r\n"),
19822 };
19823
19824 // The proxy responds to the connect with a 407, using a persistent
19825 // connection.
19826 MockRead data_reads[] = {
19827 MockRead("HTTP/1.1 200 OK\r\n"),
19828 MockRead("Content-Length: 1\r\n\r\n"),
19829 MockRead(SYNCHRONOUS, "1"),
19830 };
19831
19832 StaticSocketDataProvider data(data_reads, data_writes);
19833 session_deps_.socket_factory->AddSocketDataProvider(&data);
19834 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19835 ssl.confirm = MockConfirm(ASYNC, OK);
19836 session_deps_.enable_early_data = true;
19837 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19838
19839 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19840
19841 TestCompletionCallback callback;
19842 auto trans =
19843 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19844
19845 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19846 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19847
19848 rv = callback.WaitForResult();
19849 EXPECT_THAT(rv, IsOk());
19850
19851 const HttpResponseInfo* response = trans->GetResponseInfo();
19852 ASSERT_TRUE(response);
19853 ASSERT_TRUE(response->headers);
19854 EXPECT_EQ(200, response->headers->response_code());
19855 EXPECT_EQ(1, response->headers->GetContentLength());
19856
19857 // Check that the Write didn't get called before ConfirmHandshake completed.
19858 ASSERT_FALSE(ssl.WriteBeforeConfirm());
19859
19860 trans.reset();
19861
19862 session->CloseAllConnections();
19863}
19864
19865TEST_F(HttpNetworkTransactionTest, ZeroRTTConfirmErrorSync) {
19866 HttpRequestInfo request;
19867 request.method = "POST";
19868 request.url = GURL("https://www.example.org/");
19869 request.traffic_annotation =
19870 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19871
19872 MockWrite data_writes[] = {
19873 MockWrite("POST / HTTP/1.1\r\n"
19874 "Host: www.example.org\r\n"
19875 "Connection: keep-alive\r\n"
19876 "Content-Length: 0\r\n\r\n"),
19877 };
19878
19879 // The proxy responds to the connect with a 407, using a persistent
19880 // connection.
19881 MockRead data_reads[] = {
19882 MockRead("HTTP/1.1 200 OK\r\n"),
19883 MockRead("Content-Length: 1\r\n\r\n"),
19884 MockRead(SYNCHRONOUS, "1"),
19885 };
19886
19887 StaticSocketDataProvider data(data_reads, data_writes);
19888 session_deps_.socket_factory->AddSocketDataProvider(&data);
19889 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19890 ssl.confirm = MockConfirm(SYNCHRONOUS, ERR_SSL_PROTOCOL_ERROR);
19891 session_deps_.enable_early_data = true;
19892 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19893
19894 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19895
19896 TestCompletionCallback callback;
19897 auto trans =
19898 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19899
19900 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19901 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19902
19903 rv = callback.WaitForResult();
19904 EXPECT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
19905
19906 // Check that the Write didn't get called before ConfirmHandshake completed.
19907 ASSERT_FALSE(ssl.WriteBeforeConfirm());
19908
19909 trans.reset();
19910
19911 session->CloseAllConnections();
19912}
19913
19914TEST_F(HttpNetworkTransactionTest, ZeroRTTConfirmErrorAsync) {
19915 HttpRequestInfo request;
19916 request.method = "POST";
19917 request.url = GURL("https://www.example.org/");
19918 request.traffic_annotation =
19919 net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
19920
19921 MockWrite data_writes[] = {
19922 MockWrite("POST / HTTP/1.1\r\n"
19923 "Host: www.example.org\r\n"
19924 "Connection: keep-alive\r\n"
19925 "Content-Length: 0\r\n\r\n"),
19926 };
19927
19928 // The proxy responds to the connect with a 407, using a persistent
19929 // connection.
19930 MockRead data_reads[] = {
19931 MockRead("HTTP/1.1 200 OK\r\n"),
19932 MockRead("Content-Length: 1\r\n\r\n"),
19933 MockRead(SYNCHRONOUS, "1"),
19934 };
19935
19936 StaticSocketDataProvider data(data_reads, data_writes);
19937 session_deps_.socket_factory->AddSocketDataProvider(&data);
19938 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
19939 ssl.confirm = MockConfirm(ASYNC, ERR_SSL_PROTOCOL_ERROR);
19940 session_deps_.enable_early_data = true;
19941 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
19942
19943 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
19944
19945 TestCompletionCallback callback;
19946 auto trans =
19947 std::make_unique<HttpNetworkTransaction>(DEFAULT_PRIORITY, session.get());
19948
19949 int rv = trans->Start(&request, callback.callback(), NetLogWithSource());
19950 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
19951
19952 rv = callback.WaitForResult();
19953 EXPECT_THAT(rv, IsError(ERR_SSL_PROTOCOL_ERROR));
19954
19955 // Check that the Write didn't get called before ConfirmHandshake completed.
19956 ASSERT_FALSE(ssl.WriteBeforeConfirm());
19957
19958 trans.reset();
19959
19960 session->CloseAllConnections();
19961}
19962
[email protected]89ceba9a2009-03-21 03:46:0619963} // namespace net